<- previous index next ->
We now look at instructions in memory, how they got there and how they execute: 1. Start by using an editor to enter compiler language statements. The editor writes your source code to a disk file. 2. A compiler reads the source code disk file and produces assembly language instructions for a specific ISA that will perform your compiler language statements. The assembly language is written to a disk file. 3. An assembler reads the assembly language disk file and produces a relocatable binary version of your program and writes it to a disk file. This may be a main program or just a function or subroutine. 4. A linkage editor or binder or loader combines the relocatable binary files into an executable file. Addresses are relocated and typically all instructions are put sequentially in a code segment, all constant data in another segment, variables and arrays in another segment and possibly making other segments. The addresses in all executable files for a specific computer start at the same address. These are virtual addresses and the operating system will place the segments into RAM at other real memory addresses. 5. A program is executed by having the operating system load the executable file into RAM and set the program counter to the address of the first instruction that is to be executed in the program. All programs might have the same starting address, yet the operating system has set up the TLB to translate the virtual instruction and data addresses to real memory addresses. The real addresses are not available to the program or to a debugger. This is part of the security an operating system provides to prevent one persons program from affecting another persons program. A simple example: Compiler input int a, b=0, c=0; a = b + c; Assembly language fragment (not unique) lw $2,12($fp) b at 12 offset from frame pointer lw $3,16($fp) c at 16 offset from frame pointer add $2,$2,$3 R format instruction sw $2,8($fp) a at 8 offset from frame pointer Loaded in machine virtual address content 32-bits 8-hexadecimal digits 00000000 8FC2000C lw $2,12($fp) 00000004 8FC30010 lw $3,16($fp) 00000008 00000000 nop inserted for pipeline 0000000C 00431020 add $2,$2,$3 00000010 AFC20008 sw $2,8,($fp) Instruction field format for add $2,$2,$3 0000 0000 0100 0011 0001 0000 0010 0000 binary for 00431020 hex vvvv vvss ssst tttt dddd dhhh hhvv vvvv 6,5,5,5,5,6 bit fields 0 | 2 | 3 | 2 | 0 | 32 decimal values of fields Instruction field format for lw $2,12($fp) $fp is register 30 1000 1111 1100 0010 0000 0000 0000 1100 binary for 8FC2000C hex vvvv vvxx xxxd dddd aaaa aaaa aaaa aaaa 6,5,5,16 bit fields 35 | 30 | 2 | 12 decimal values of fields The person writing the assembler chose the format of an assembly language line. The person designing the ISA chose the format of the instruction. Why would you expect them to be in the same order?A very simplified data flow of the add instruction. From the registers to the ALU and back to the registers.
For Homework 3 /* matmul2.c 100*100 matrix element by element multiply */ #include <stdio.h> int main() { const int N = 100; double a[N][N]; /* input matrix */ double b[N][N]; /* input matrix */ double c[N][N]; /* result matrix */ int i,j; printf("starting multiply \n"); a[1][1] = 3.5; b[1][1] =1.2; /* not a valid benchmark, most elements zero */ for(i=0; i<N; i++){ for(j=0; j<N; j++){ front: c[i][j] = a[i][j]*b[i][j]; /* most time spent here! */ back:; } } printf("a result %g \n", c[1][1]); /* prevent dead code elimination */ return 0; } a[i][j]*b[i][j] | | The opcode for this multiply is "mul.d" read as multiply double The "front" and "back" labels may help you find the mul.d instructions. To use the debugger, follow these steps exactly, else you are on your own. c89 -g3 -O3 matmul2.c # need debug, -g3, for "stop main" to work dbx -d a.out > hex.out stop main rerun list 1,26 (#1)/100X (#1)/100i q The file hex.out has the source listing with line numbers, the hex address and hex instructions as loaded in memory and the disassembly with hex address and decoded instruction. An instruction field format is on page 207 of textbook. See mul.d . mul.d is the MIPS=SGI double precision floating point multiply, "R" format. Watch out for where the register values are placed. If not covered in Lecture 3, note number of registers in the IA-64 Itanium
<- previous index next ->