Two pass assembler and Emulator for an extended SIMPLE instruction set
Instruction Set
| Mnemonic | Opcode | Operand | Formal Specifications | Description |
|---|---|---|---|---|
| data | value | Reserve a memory location, initialized to the value specified | ||
| ldc | 0 | value | B := A; A := value; | Load accumulator with the value specified |
| adc | 1 | value | A := A + value; | Add the value specified to the accumulator |
| ldl | 2 | offset | B := A; A := memory[SP + offset]; | Load local |
| stl | 3 | offset | memory[SP + offset] := A; A := B; | Store local |
| ldnl | 4 | offset | A := memory[A + offset]; | Load non-local |
| stnl | 5 | offset | memory[A + offset] := B; | Store non-local |
| add | 6 | A := B + A; | Addition | |
| sub | 7 | A := B - A; | Subtraction | |
| shl | 8 | A := B << A; | Shift left | |
| shr | 9 | A := B >> A; | Shift right | |
| adj | 10 | value | SP := SP + value; | Adjust SP |
| a2sp | 11 | SP := A; A := B; | Transfer A to SP | |
| sp2a | 12 | B := A; A := SP; | Transfer SP to A | |
| call | 13 | offset | B := A; A := PC; PC := PC + offset; | Call procedure |
| return | 14 | PC := A; A := B; | Return from procedure | |
| brz | 15 | offset | if A == 0 then PC := PC + offset; | If accumulator is zero, branch to specified offset |
| brlz | 16 | offset | if A < 0 then PC := PC + offset; | If accumulator is less than zero, branch to specified offset |
| br | 17 | offset | PC := PC + offset; | |
| HALT | 18 | Stop the emulator. This is not a `real' instruction, but needed to tell your emulator when to finish. | ||
| SET | 19 | value | Set the label on this line to the specified value (rather than the PC). This is an optional extension, for which additional marks are available. |
● If a value is in Hexadecimal it would always start with ‘0x’.
● If a value is in Octal it would always start with ‘0’.
● If any operand is missing or invalid the error is ‘improper operand’.
● The Pass1 of the assembler outputs no code and does not fail on undefined labels.
● The size of DATA and SET instructions is assumed to be 32 bits.
● The labels can have ‘_’ anywhere in their names.
EXPLANATION OF C++ Code:
● The data structures like maps, vectors and arrays are declared to store values such as instructions, operands, opcodes, etc.
● Declared functions like removeUneccesarySpaces, removeComment, opcode_to_hex_string, etc. for carrying out various functions.
● In main first the init() function is called to initialize instruct_table and error_table. Then the extension of the file is checked. If the extension is not ‘.asm’ then error is printed on the screen. Then Pass1() and Pass2() are called.
● The SET instruction is implemented.
● In Pass1() the program is read line by line and errors like ‘extra on end of line’, ‘improper operand’, etc are taken into account. The instructions without labels and offsets are taken care of. The program counter is also dealt with in this pass.
● In Pass2() the errors regarding labels are taken into account. The ‘.lst’ , ‘.log’ and ‘.o’ files are created.
● Finally in Pass2() writeObjFile function is called if there are no errors. We are opening a .o file as “wb” which stands for writebinary. The hex machine code obtained is converted to int and written into the ‘.o’ file.
Compiling and Using the assembler:
Use the following commands:
● g++ asm.cpp -o asm
-> After this an asm executable file will be created.
● ./asm filename.asm
-> After this command a '.o' will be created. This is a binary file and its contents can be observed using 'hexdump filename.o' commmand.
Compiling and Using the emulator:
Use the following commands:
● g++ emu.cpp -o emu
-> After this an emu executable file will be created.
● ./emu filename.o
-> This will list the functions available in the emulator and a log file will also be generated
-trace show instruction trace
-read show memory reads
-write show memory writes
-before show memory dump before execution
-after show memory dump after execution
-wipe wipe written flags before execution
-isa display ISA
-> Now use one of these commands e.g './emu -trace filename.o' and observe the results.
Both the assembler and emulator were tested in Ubuntu OS.