Reference no: EM13935009
1. The aim of this programming assignment is to try out some of the ideas you learnt on interpretation. It is to be done on an individual basis.
2. Write a program (C language preferred) that will emulate a x86 processor
3. Input: The input to the program shall be a text file containing binary encoding of some x86 code. Here is a sample input file ("sampleinput.txt"): 8d 4c 24 04 83 e4 f0 50 c1 f8 02 34 2e 89 e5 45 83 ec 04 80 7c 24 04 81 5d This is for the following IA32 instructions: leal 4(%esp), %ecx andl $-16, %esp pushl %eax sar $0x2,%eax xor $0x2e,%al movl %esp, %ebp inc %ebp subl $4, %esp cmpb $0x81, 4(%esp) popl %ebp
4. First, try to decipher the instructions by hand. You will need to refer to the instruction set definition from the official Intel site: http://www.intel.com/ products/processor/manuals/.
You may want to zoom into Appendix A and B found in "Intel® 64 and IA-32 Architectures Developer's Manual: Vol. 2"
5. An utility in x86-Linux will help you to generate more test code. First, take a program and compile it for the 32-bit IA32 instruction set. Suppose you test input is t.c. Do this: $ gcc -m32 -O3 t.c
6. $ objdump -D a.out
7. You will see something like this: ‘08048250' is the memory address (in hexadecimal) of the routine _init. Note that this is only a sample. The actual numbers you see will be different.
The first instruction is ‘push %ebp' and the binary encoding of that instruction is 55 (hexadecimal). Using cut and paste from appropriate parts of the output of objdump, create test inputs like the sample-input.txt.
8. Your program will read in the input file and emulate the encoded instructions. At the end, your code should dump out all the registers. Here is the default input for all the registers that you should use: eax 0xbf8db144 ecx 0x88c5cffb edx 0x1 ebx 0xae5ff4 esp 0xbf8db0bc ebp 0xbf8db118 esi 0x9a0ca0 edi 0x0 eip 0x8048354 eflags 0x246 cs 0x73 ss 0x7b ds 0x7b es 0x7b fs 0x0 gs 0x33
9. What you program should do is a bit like gdb - step through the instructions one by one, printing out all the registers' content after each instruction's execution. Your program should also simulate memory (not all 4GB but just the top of the stack) such that if your input writes to A to memory location X, then a later read of memory location X should return AAbstract. Romer et al (ASPLOS 96) examined several interpreters and concluded that they behave much like general purpose integer programs such as gcc. We show that there is an important class of interpreters which behave very differently. Efficient virtual machine interpreters perform a large number of indirect branches (3.2%-13% of all executed instructions in our benchmarks, taking up to 61%-79% of the cycles on a machine with no branch prediction). We evaluate how various branch prediction schemes and methods to reduce the mispredict penalty affect the performance of several virtual machine interpreters. Our results show that for current branch predictors, threaded code interpreters cause fewer mispredictions, and are almost twice as fast as switch based interpreters on modern superscalar architectures.