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
LOADinstruction. Memory access is facilitated throughSTOREandLOADMinstructions, 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
INandOUTinstructions 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, r2Description: Copy the value of register
r2into registerr1.Syntax:
MOV destination, sourceExample:
MOV r1, r2Operation:
r1 = r2LOAD r1, #5Description: Load the immediate value
5into registerr1.Syntax:
LOAD register, immediate_valueExample:
LOAD r1, #5Operation:
r1 = 5STORE r1, 0Description: Store the value of register
r1into memory address0.Syntax:
STORE register, memory_addressExample:
STORE r1, 0Operation:
memory[0] = r1LOADM r1, 0Description: Load the value from memory address
0into registerr1.Syntax:
LOADM register, memory_addressExample:
LOADM r1, 0Operation:
r1 = memory[0]
Arithmetic Instructions
ADD r1, r2Description: Add the value of register
r2to registerr1.Syntax:
ADD destination, sourceExample:
ADD r1, r2Operation:
r1 = r1 + r2SUB r1, r2Description: Subtract the value of register
r2from registerr1.Syntax:
SUB destination, sourceExample:
SUB r1, r2Operation:
r1 = r1 - r2MUL r1, r2, r3Description: Multiply the value of register
r2by the value of registerr3and store the result in registerr1.Syntax:
MUL destination, source1, source2Example:
MUL r1, r2, r3Operation:
r1 = r2 * r3MUL r1, r2, r3Description: Divide the value of register
r2by the value of registerr3and store the result in registerr1.Syntax:
DIV destination, source1, source2Example:
DIV r1, r2, r3Operation:
r1 = r2 / r3INC r1Description: Increment the value of register
r1by1.Syntax:
INC registerExample:
INC r1Operation:
r1 = r1 + 1DEC r1Description: Decrement the value of register
r1by1.Syntax:
DEC registerExample:
DEC r1Operation:
r1 = r1 - 1
Control Flow Instructions
JMP addressDescription: Jump to the specified address.
Syntax:
JMP addressExample:
JMP 100Operation:
PC = address(PC stands for Program Counter)JZ addressDescription: Jump to the specified address if the zero flag is set.
Syntax:
JZ addressExample:
JZ 100Operation:
if (ZF == 1) PC = address(ZF stands for Zero Flag)JNZ addressDescription: Jump to the specified address if the zero flag is not set.
Syntax:
JNZ addressExample:
JNZ 100Operation:
if (ZF == 0) PC = address
Input/Output Instructions
IN r1Description: Input a value into register
r1.Syntax:
IN registerExample:
IN r1Operation:
r1 = input_value(Assuming input_value is obtained from an input device or user input)OUT r1Description: Output the value of register
r1.Syntax:
OUT registerExample:
OUT r1Operation:
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.