Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
Procedures that don't call others are called leaf procedures, procedures that call others are called nested procedures. Problems may arise now, for example the main program calls procedure A with the argument 3 in $a0 and the return address in $ra. Procedure A then calls procedure B with the argument 7 in $a0 and with its return address in $ra. We must preserve these values across calls. Lets look at a translation of the recursive factorial function in C.
1
Factorial in C
int fact(int n) { if(n < 1) return (1); else return (n * fact -1); } As we can C the function calls itself multiple times. The argument n is sent to the function via the register $a0, which is saved on the stack along with $ra.
2
Factorial in Assembly
fact: subi $sp,$sp,8 # make room for 2 items sw $ra,4($sp)# push the return address sw $a0,0($sp)# push the argument n slt $t0,$a0,1 # test for n<1 beq $t0,$zero,L1 # if n>=1 goto L1 li $v0,1 # pseudoinstruction $v0=1 addi $sp,$sp,8 # pop 2 items off stack jr $ra The following is the recursive call to fact(n-1) L1: subi $a0,$a0,1 # n-jal fact # call fact(n-1) lw $a0,0($sp) # return from fact(n-1) lw $ra,4($sp) # pop n and return address addi $sp,$sp,8 # pop 2 items off stack mult $v0,$a0,$v0 # return n * fact(n-1) 3 jr $ra
Procedure Frame
The stack above $sp is preserved ( ) by making sure that the callee ( ) is doesn't write above $sp. $sp is preserved by adding exactly the same amount subtracted from it. All other registers are preserved by being saved on the stack. The stack also contains local variables that don't fit into registers. The segment of the stack containing the saved registers and local variables is called the procedure frame or activation record.
4
Frame Pointer
Some MIPS software use the register $fp to point to the first word of the frame of a procedure.
High address
$fp $fp
$sp $fp Saved argument registers (if any) Saved return address Saved saved registers (if any)
$sp
Low address
a. b. c.
Strcpy in C++
void strcpy(char x[], char y[]) { int i; i=0; while((x[i]=y[i]) != 0) i++ } The base address for the arrays x and y are in registers $a0 and $a1.
Strcpy in Assembly
strcpy: add $t0,$zero,$zero #$t0=0 L1: add $t1,$a1,$t0 #$t1=&y[i] lb $t2,0($t1) # $t2=y[i] add $t3,$a0,$t0 #$t3=&x[i] sb $t2,0($t3) # x[i]=y[i] addi $t0,$t0,1 # i++ bne $t2,$zero,L1 # if y[i]!=0 loop jr $ra # return
Immediate Operands
As mentioned before the I-format instruction contains a 16 bit constant called an immediate. Using I-type instructions avoids loading values from memory into a register. Examples of instruction which use immediate values are: multi $s0,$s1,4 # $s0=$s1*4 slti $t0,$s2,10 # $t0=1 if $s2<10 But if a constant is larger than 16 bits? MIPS provides an instruction lui that loads a 16 bit constant into the upper half of an register. In order to load the value: 0000 0000 0011 1101 0000 1001 0000 0000 into $s0 we must perfrom: lui $s0,61 #61d = 0000 0000 0011 1101 addi $s0,$s0,2304 # 2304d = 0000100100000000 10
PC-Relative Adressing
The Program Counter (PC) is a register the
software can't access directly, that always contains the address of the current instruction being executed. Thus if we use the PC as the register to add to the branch address we can always branch within a range of -215 to 215 bytes of the current instruction. This is enough for most loops and if statements. This form of addressing is called PC-relative addressing. Procedures are not usually within a short range of the current instruction and thus jal is a J-type 12 instruction
The branch instruction adds 8 bytes to the PC and not 12 because the PC is automatically incremented by 4 when an instruction is executed. In fact the branch offset is 2 not 8. All MIPS instructions are 4 bytes long thus the offset is in words not bytes. The range of a branch has 13 been multiplied by 4.
Pseudodirect Addressing
The 26-bit field in the jump instruction is also a word address. Thus it is a 28-bit address. But the PC holds 32-bits? The MIPS jumps instruction replaces only the lower 28 bits of the PC, leaving the 4 highest bits of the PC unchanged. The loader and linker must avoid placing a program across an address boundary ( ) of 256MB (64 million instructions). Otherwise a j must be replaced with a jr.
14
Register
Byte
Halfword
Word
PC
Word
PC
Word
16
80x86 Registers
Name EAX ECX EDX EBX ESP EBP ESI EDI CS SS DS ES FS GS EIP EFLAGS 31 0 Use GPR 0 GPR 1 GPR 2 GPR 3 GPR 4 GPR 5 GPR 6 GPR 7 Code segment pointer Stack segment pointer (top of stack) Data segment pointer 0 Data segment pointer 1 Data segment pointer 2 Data segment pointer 3 Instruction pointer (PC) Condition codes
18
19
c. MOV EBX, [EDI + 45] 6 MOV d. PUSH ESI 5 PUSH 3 Reg 1 1 d w 8 r-m postbyte 8 Displacement
20