Introduction
Dr. T's Toy Assembler is an emulator for a minimalist (14 instruction) language for teaching the basics of ASM programming.
Features of the Language
- Register-Based Operations: The language utilizes registers named
r1
,r2
,r3
, etc., to perform operations. Registers are fast storage locations within the CPU that hold data and addresses temporarily during execution. - Immediate and Memory Access: Immediate values can be directly loaded into registers using the
LOAD
instruction. Memory access is facilitated throughSTORE
andLOADM
instructions, allowing values to be stored in and loaded from specific memory addresses. - Arithmetic and Logic Operations: Basic arithmetic operations such as addition (
ADD
), subtraction (SUB
), multiplication (MUL
), division (DIV
),increment (INC
), and decrement (DEC
) are supported. Logical operations can be implemented using combinations of arithmetic instructions and conditional jumps. - Conditional and Unconditional Jumps: Unconditional jumps (
JMP
) and conditional jumps (JZ
,JNZ
) allow for control flow manipulation, enabling the implementation of loops, conditional statements, and other control structures. - Input and Output Operations: The
IN
andOUT
instructions facilitate interaction with input and output devices, allowing for data exchange between the CPU and peripherals. - Flags for Conditional Operations: The language supports flags, which are special indicators used to influence the flow of execution based on the results of previous operations.
Instruction Set
Data Movement Instructions
MOV r1, r2
Description: Copy the value of register
r2
into registerr1
.Syntax:
MOV destination, source
Example:
MOV r1, r2
Operation:
r1 = r2
LOAD r1, #5
Description: Load the immediate value
5
into registerr1
.Syntax:
LOAD register, immediate_value
Example:
LOAD r1, #5
Operation:
r1 = 5
STORE r1, 0
Description: Store the value of register
r1
into memory address0
.Syntax:
STORE register, memory_address
Example:
STORE r1, 0
Operation:
memory[0] = r1
LOADM r1, 0
Description: Load the value from memory address
0
into registerr1
.Syntax:
LOADM register, memory_address
Example:
LOADM r1, 0
Operation:
r1 = memory[0]
Arithmetic Instructions
ADD r1, r2
Description: Add the value of register
r2
to registerr1
.Syntax:
ADD destination, source
Example:
ADD r1, r2
Operation:
r1 = r1 + r2
SUB r1, r2
Description: Subtract the value of register
r2
from registerr1
.Syntax:
SUB destination, source
Example:
SUB r1, r2
Operation:
r1 = r1 - r2
MUL r1, r2, r3
Description: Multiply the value of register
r2
by the value of registerr3
and store the result in registerr1
.Syntax:
MUL destination, source1, source2
Example:
MUL r1, r2, r3
Operation:
r1 = r2 * r3
MUL r1, r2, r3
Description: Divide the value of register
r2
by the value of registerr3
and store the result in registerr1
.Syntax:
DIV destination, source1, source2
Example:
DIV r1, r2, r3
Operation:
r1 = r2 / r3
INC r1
Description: Increment the value of register
r1
by1
.Syntax:
INC register
Example:
INC r1
Operation:
r1 = r1 + 1
DEC r1
Description: Decrement the value of register
r1
by1
.Syntax:
DEC register
Example:
DEC r1
Operation:
r1 = r1 - 1
Control Flow Instructions
JMP address
Description: Jump to the specified address.
Syntax:
JMP address
Example:
JMP 100
Operation:
PC = address
(PC stands for Program Counter)JZ address
Description: Jump to the specified address if the zero flag is set.
Syntax:
JZ address
Example:
JZ 100
Operation:
if (ZF == 1) PC = address
(ZF stands for Zero Flag)JNZ address
Description: Jump to the specified address if the zero flag is not set.
Syntax:
JNZ address
Example:
JNZ 100
Operation:
if (ZF == 0) PC = address
Input/Output Instructions
IN r1
Description: Input a value into register
r1
.Syntax:
IN register
Example:
IN r1
Operation:
r1 = input_value
(Assuming input_value is obtained from an input device or user input)OUT r1
Description: Output the value of register
r1
.Syntax:
OUT register
Example:
OUT r1
Operation:
output(r1)
(Assuming output is sent to an output device or display)
Using Labels
Labels are STRING identifiers used to mark specific locations in your code. They are useful for making your code more readable and for facilitating jumps to different sections of the program.
Defining Labels
To define a label, simply write the label name followed by a colon (:
) at the desired location in your code. Labels are usually placed before a section of code to which you might want to jump.
start:
LOAD r1, #10 ; Load immediate value 10 into r1
ADD r1, r2 ; Add the value of r2 to r1
JNZ end ; Jump to the label 'end' if Zero Flag is not set
INC r1 ; This line will be skipped if ZF is set
end:
OUT r1 ; Output the value of r1
Using Labels with Jumps
Labels can be used with jump instructions (JMP
, JZ
, JNZ
) to create more complex control flows. You can use labels to jump to different parts of your code, enabling loops and conditional execution.
LOOP_START:
LOAD r1, #5 ; Load immediate value 5 into r1
DEC r1 ; Decrement r1
JNZ LOOP_START ; Jump back to 'LOOP_START' if ZF is not set (r1 != 0)
OUT r1 ; Output the final value of r1 after loop ends
Flags Explained
Flags are special bits that store information about the state of the CPU or the results of operations. They are typically used to make decisions during program execution. In this language, the primary flag used is the Zero Flag (ZF).
Zero Flag (ZF)
- Purpose: The Zero Flag is used to indicate whether the result of an operation is zero.
- Set: The Zero Flag is set (ZF = 1) if the result of an operation (such as
ADD
,SUB
,MUL
,DIV
) is zero. - Cleared: The Zero Flag is cleared (ZF = 0) if the result of an operation is non-zero.
- Usage: The Zero Flag is primarily used in conditional jump instructions (
JZ
,JNZ
) to determine the flow of execution.