Subroutines Natawut Nupairoj Assembly Language 1 Subroutines A
Subroutines Natawut Nupairoj Assembly Language 1
Subroutines • A subroutine is a piece of program codes that performs some particular functions. – Function, Procedure, Method • A subroutine must behave: – in-line execution: flow naturally. – no unintended side effects: must declare explicitly which registers will be changed which will be not after the call. – multiple arguments: should allow a caller to pass more than one argument. Natawut Nupairoj Assembly Language 2
Subroutine • Thus, CPU must provide: • Call/return mechanism. – Save the address of the instruction being executed (pc) of the caller so that, when return, it can resume execution at the next instruction. • A register protection mechanism. – How to save the values of the register before the call and restore the values back when returns from calling. • An argument passing convention. – An agreement between caller and callee on how arguments are to be passed. Natawut Nupairoj Assembly Language 3
Call/Return Mechanism • • • Two special instructions: call and ret. Use “call” to call for a particular subroutine. Use “ret” to return from the subroutine. Both have a delay slot. Example: . global sub_a: save %sp, -96, %sp. . . call sub_b nop. . . Natawut Nupairoj . global sub_b: save %sp, -64, %sp. . ret restore ! AFTER ret Assembly Language 4
Register Saving • Subroutine must explicitly declare which registers will be changed, which won’t. • Subroutine also needs to use registers for computation. • To reduce the side-effect (due to modifying registers), we will save values in registers before doing anything and restore back before return. • In most CPUs, we will push/pop values in registers to/from the stack. • In SPARC, we have save/restore instructions. Natawut Nupairoj Assembly Language 5
Register Saving • Save: allocate space in stack and save registers (in special ways. ( • Restore: deallocate space and restore registers (in special ways. ( • Pushing/Poping registers to/from stack requires lots of time. • In SPARC, we use the concept “Register Window” (performed by Save and. Restore. ( Natawut Nupairoj Assembly Language 6
SPARC Register • SPARC has 8 global registers and 128 general registers. • For general registers, only 24 registers are active or “mapped” at any time. • Thus this makes 24 + 8 = 32 registers available. • The mapping mechanism is called “register window”. • SPARC has two internal pointers: – CWP: Current Window Pointer – WIM: Window Invalid Mark Natawut Nupairoj Assembly Language 7
SPARC Register Window Natawut Nupairoj Assembly Language 8
Effect of Save Instruction Natawut Nupairoj Assembly Language 9
Effect of Save Instruction Natawut Nupairoj Assembly Language 10
Effect of Save Instruction Before “Save” After “Save” Natawut Nupairoj Assembly Language 11
Effect of Save Instruction • • • Provide a new set of local registers. Provide a new set of out registers. Make the old “out” registers into the new “in” registers. In the process, the old %sp becomes the new %fp. Global registers remain unchanged. Natawut Nupairoj Assembly Language 12
Register Window Overflow • Since we have only 128 general registers, we can save at most 7 sets of registers. • This means we can “save” 7 times without having to “restore. ” • What happen if we run out of registers? • We save it to the main memory, provided in the stack!!! • Remember, every time we allocate spaces in stack with “save”, we always reserve 64 bytes to save registers. Natawut Nupairoj Assembly Language 13
Register Window Overflow Natawut Nupairoj Assembly Language 14
Arguments to Subroutines • How we can pass arguments to a subroutine? • Remember, the “out” registers of the caller become the “in” registers of the called subroutine. • However, we can passed at most 6 registers (%o 0 -%o 5) because %o 6 is the stack pointer and %o 7 contains the return address. • The called subroutine accesses the arguments via the “in” registers. Natawut Nupairoj Assembly Language 15
Passive Arguments Natawut Nupairoj Assembly Language 16
Our Fifth Program int mul(int a, int b) { int r; register int i; r = 0; i = b; while(i > 0) { r = r + a; i--; } main() { int r; short x, y; x = 10; y = 30; r = mul(x, y); } return r; } Natawut Nupairoj Assembly Language 17
Our Fifth Program mul: define(mul_a_r, i 0) define(mul_b_r, i 1) define(mul_r_s, -4) define(mul_i_r, l 0) define(r_s, -4) define(x_s, -6) define(y_s, -8). global mul save %sp, (-64 -4)&-8, %sp clr %l 1 st %l 1, [%fp + mul_r_s] ! r = 0; mov %mul_b_r, %mul_i_r ! i = b; Natawut Nupairoj Assembly Language 18
Our Fifth Program loop: cmp ble nop %mul_i_r, 0 done ld add st [%fp + mul_r_s], %l 1, %mul_a_r, %l 1 ! r + a %l 1, [%fp + mul_r_s] ! r = r + a; sub ba nop %mul_i_r, 1, %mul_i_r ! i--; loop Natawut Nupairoj Assembly Language ! start while loop 19
Our Fifth Program done: main: ld [%fp + mul_r_s], %i 0 ! return r; ret restore ! After ret. global main save %sp, (-64 -8)&-8, %sp mov 10, %l 0 sth %l 0, [%fp + x_s] ! x = 10; mov 30, %l 0 sth %l 0, [%fp + y_s] ! y = 30; Natawut Nupairoj Assembly Language 20
Our Fifth Program ldsh [%fp + x_s], %o 0 ldsh [%fp + y_s], %o 1 call mul nop st %o 0, [%fp + r_s] mov ta 1, %g 1 0 Natawut Nupairoj Assembly Language ! prepare first arg. ! prepare second arg. 21
Optimizing the Common Case • Why does SPARC have 128 registers (which can provide upto 7 saves before overflowed) ? • Why does SPARC have 8 “out” registers to pass arguments to a subroutine ? • The SPARC designers studied real programs and conclude that these are quite common. • We can have more registers, but it may cost more and we will not gain much improvement. • This is called “optimizing the common case”. Natawut Nupairoj Assembly Language 22
Return Values • A subroutine that returns a value is called a function. • We can store the returned value in the “in” registers of the called subroutine and they will become the “out” registers when return. • In sub_a: In sub_b: . . . call sub_b nop st %o 0, [%fp-4]. . . Natawut Nupairoj . . . add %o 0, %l 2, %l 3 mov %l 3, %i 0 ret restore Assembly Language 23
Return Values • Or we can use “restore” to return value to any register. restore %l 3, %l 0, %i 5 • This adds %l 3 with %l 0 (both from the called subroutine registers) then stores the result in %i 5 of the calling subroutine (or after “restore”). • However, typical common convention is to return value in %o 0 (of the calling subroutine). Natawut Nupairoj Assembly Language 24
Passing many Arguments • In some subroutines, passing only 6 arguments may not be enough. • If more than 6 arguments are required, we store the rest in the stack before calling. • For example, main calls: sub 1(1, 2, 3, 4, 5, 6, 7, 8); • We put first 6 arguments in %o 0 -%o 5. • Then put the last two arguments in the stack. • Thus, we must allocate more spaces before calling. Natawut Nupairoj Assembly Language 25
Passing many Arguments (main stack( Natawut Nupairoj Assembly Language 26
Passing many Arguments Natawut Nupairoj Assembly Language 27
Passing many Arguments main: save. . . add mov st mov mov mov Natawut Nupairoj %sp, -64, %sp, -8, %sp ! Allocate for 2 args. 8, %o 0, [%sp + 8+64] 7, %o 0, [%sp + 4+64] 6, %o 5 5, %o 4 4, %o 3 3, %o 2 2, %o 1 Assembly Language 28
Passing many Arguments call _sub 1 mov 1, %o 0 sub %sp, -8, %sp. . . ! Delay Slot ! Release stack. • In sub 1: save ld ld add sub. . . Natawut Nupairoj %sp, [%fp %o 0, %i 5, %o 0, (-92&-8), %sp + 8+64], %o 0 + 4+64], %o 1, %o 0, %o 0 %i 4, %o 0 Assembly Language ! The last two args. ! The sixth argument. ! The fourth argument. 29
Our Sixth Program main() { int x, y; x = y = x = 10, 12; x + 1; sub 1(2, 0, x, y, x+5, 3, y); } Natawut Nupairoj sub 1(int a, int b, int c, int d, int e, int f, int g, int h) { int r; r = a + b + c + d + e + f + g + h; return r; } Assembly Language 30
Our Sixth Program define(x_s, -4) define(y_s, -8) define(arg 7_s, 64+4) define(arg 8_s, 64+8) ! main define(a_r, define(b_r, define(c_r, define(d_r, define(e_r, define(f_r, define(g_s, define(h_s, define(r_s, ! sub 1 Natawut Nupairoj %i 0) %i 1) %i 2) %i 3) %i 4) %i 5) arg 7_s) arg 8_s) -4) ! 7 th arg. ! 8 th arg. Assembly Language 31
Our Sixth Program main: . global main save %sp, (-64 -8)&-8, %sp mov 12, %l 0 st %l 0, [%fp + x_s] add %l 0, 1, %l 0 st %l 0, [%fp + y_s] add %sp, -8, %sp mov ld ld 2, %o 0 0, %o 1 [%fp + x_s], %o 2 [%fp + y_s], %o 3 Natawut Nupairoj Assembly Language ! x = 12; ! y = x + 1; ! ! ! Reserve the 7 th The 1 st The 2 nd The 3 rd The 4 th stack for and 8 th args. arg. 32
Our Sixth Program ld add mov mov st ld st call nop st sub [%fp + x_s], %l 0, 5, %l 0, %o 4 10, %o 5 3, %l 0, [%sp + arg 7_s] [%fp + y_s], %l 0, [%sp + arg 8_s] sub 1 %o 0, [%fp + x_s] %sp, -8, %sp ! Store result from sub 1 ! Release stack mov ta 1, %g 1 0 ! Exit program Natawut Nupairoj Assembly Language ! The 5 th arg. ! The 6 th arg. ! 3 is the 7 th arg. ! Y is the 8 th arg. 33
Our Sixth Program sub 1: . global sub 1 save %sp, (-64 -4)&-8, %sp add %i 0, %i 1, %l 0 add %l 0, %i 2, %l 0 add %l 0, %i 3, %l 0 add %l 0, %i 4, %l 0 add %l 0, %i 5, %l 0 ld [%fp + g_s], %l 1 add %l 0, %l 1, %l 0 ld [%fp + h_s], %l 1 add %l 0, %l 1, %l 0 st %l 0, [%fp + r_s] ld [%fp + r_s], %o 0 ret restore %o 0, 0, %o 0 Natawut Nupairoj Assembly Language ! Read the 7 th arg. ! Read the 8 th arg. ! Store result to r. ! return r; ! After ret 34
- Slides: 34