CS520
Spring 2014
Programming Assignment 3
Due Thursday March 6 (extension granted to Saturday March 8)
Write a C function, translateBinary, to translate vm520 instructions to
Intel 64 instructions.
The function should take three arguments:
- The name of the vm520 object file to be translated.
- A buffer into which the Intel 64 instructions should be written.
- The length of the buffer in units of bytes.
You may make a number of simplifying assumptions about the vm520 object
file being translated:
- The first instruction in the object code section will be a JMP
instruction which will jump over a block of data.
- All data words in the program will be in this block.
- All other words in the object code section will be instructions that
should be translated.
- The only registers that will appear in instructions are R0-R5.
- The following instructions will not appear: ADDF, SUBF, DIVF, MULF,
CALL, RET, CMPXCHG, GETPID, GETPN, PUSH and POP.
- The LOAD, STORE, LDADDR, LDIND and STIND instructions will only refer to
words in the data block.
- The JMP, BEQ, BLT and BGT instructions will not branch into the data
block.
Your translation should follow these strategies:
- vm520 data words should be translated to Intel quadwords and all
vm520 integer operations should be performed using Intel quadword
operations.
- The supported vm520 registers should be implemented using these
Intel 64 registers: R0=>R8, R1=>R9, R2=>R10, R3=>R11, R4=>RCX and R5=>RSI.
(This was a late edit to change the mapping of R5 to RSI rather
than RDX, because RDX is used in the Intel divide instruction. It is okay
to continue mapping R5 to RDX, but then you will need to save and restore
it in your translation of the vm520 division instruction.)
- The initial JMP instruction should be implemented with an Intel
JMP instruction, which should be padded with bytes containing zero to fill up
8 bytes.
This will then allow each vm520 data word to be addressed in Intel memory
as an offset from the beginning of the translated code, where the
offset of the data word is computed by multiplying the vm520 address
by eight.
At run time the address of the beginning of the translated code
will be available in the RDI register.
- Because Intel 64 instructions are variable length, the
JMP, BEQ, BLT and BGT instructions will be tricky to translate.
You will need to keep track of the number of bytes contained in
each Intel 64 instruction that you generate, so that you can
translate vm520 addresses to Intel 64 addresses.
This means you will not be able to compute the Intel 64 displacements
for forward jumps and branches until all the instructions in between
have been translated.
One approach would be to translate all the instructions, leaving
space for the forward displacements, and then return and fill in
the correct displacements once all the instructions have been processed.
For this reason it is fine to always use 32-bit displacements.
- The LDADDR, LDIND and STIND instructions will also be tricky.
The translation of a LDADDR instruction will need to load the vm520 address
into the Intel 64 register.
The LDIND and STIND instructions will be translated into Intel 64
instructions that will convert the vm520 address in the vm520 register
to a Intel 64 address that is then used to load an Intel 64 register.
- To keep things simple, you may use Intel 64 32-bit immediate values
to implement all vm520 immediate values.
- Translate the vm520 HALT instruction to the Intel 64 RET instruction.
In addition, if the object code section does not end in a HALT instruction,
generate an Intel 64 RET instruction at the end of the generated Intel 64 code.
During translation you may print an appropriate error message to stderr
and halt the program if any of these things happen:
- One of the simplifying assumptions given above is violated.
- The allocated buffer is not long enough.
- The object file cannot be opened.
- The object file is corrupted.
- The object file contains an outsymbol.
The directory ~cs520/public/prog3 contains sample code for
this assignment:
- allocateInstructionBuffer.c: contains code for allocating a buffer
where Intel 64 instructions can be written and then executed.
You should not change this code.
And please note that this code cannot be compiled with the -std=c99 flag.
- translateSumVector.c: contains an implementation of translateBinary
that does not read a vm520 object file, but rather just hardcodes
Intel 64 instructions to implement the sumVector.obj example that
is available on agate in ~cs520/public/vm520-examples.
This file contains a lot of examples of how to translate vm520
instructions to Intel 64 instructions.
- mainSumVector.c: a main program that utilizes the other two files.
Especially note how the translated code is executed.
Also note how the main program can reach into the translated code to
retrieve the result of the computation, but must remember that vm520
words are implemented with Intel quadwords.
- This code can be compiled and executed in the following way:
gcc -c -Wall allocateInstructionBuffer.c
gcc -Wall -std=c99 translateSumVector.c mainSumVector.c allocateInstructionBuffer.o
a.out
Your program will be graded primarily by testing it for correct
functionality:
- 60 points - handle vm520 programs that contain
HALT, LOAD, STORE and LDIMM instructions (as well as the initial JMP
instruction and a data section).
- 20 points - also handle ADDI, SUBI, DIVI and MULI instructions.
- 10 points - also handle BLT, BGT and BEQ instructions, as well
as the general use of the JMP instruction.
- 10 points - also handle LDADDR, LDIND and STDIND instructions.
These items are listed in the order that you should tackle them.
For example, the testing of the branch/jump instructions will assume
that you have HALT, LOAD, STORE, LDIMM, ADDI, SUBI, DIVI and MULI working.
In addition, remember, you may lose points if your program is not properly
structured or adequately documented.
See the mandatory guidelines given in the
course
overview webpage.
Your programs will be graded using agate.cs.unh.edu
so be sure to test in that environment.
You should submit all the source code for your implementation of
the translateBinary routine in a single file called
translateBinary.c.
You must turn-off any debugging code before you submit your
program.
Your submitted file will be compiled using the following:
gcc -c -g -Wall -std=c99 translateBinary.c
Note: you are only submitting the one file, translateBinary.c, so
do not put any of your code in any other file.
In particular, translateBinary.c should not include any files that
you created.
It should only include standard system header files.
In addition, it should not contain a main function,
nor should it contain the allocateInstructionBuffer function.
Your programs should be submitted for grading from agate.cs.unh.edu.
To turn in this assignment, type:
~cs520/bin/submit prog3 translateBinary.c
Submissions can be checked by typing:
~cs520/bin/scheck prog3
This assignment is due Thursday March 6 (extension granted to Saturday March 8).
The standard late policy concerning late submissions will be in
effect.
See the course
overview webpage.
Remember: as always you are expected to do your own work on this assignment.
Last modified on March 3, 2014.
Comments and questions should be directed to
hatcher@unh.edu