Function all Mechanism /* Simple Program */ #define get_int() IN KEYOARD #define put_int(val) LD A val \ OUT MONITOR int add_two(int a, int b) { int tmp; tmp = a+b; return tmp; } local auto variable stack 영역에자리잡는다. int sum, val1, val2; main() { put_int( add_two(get_int(),get_int())); } SIMPLE START 0 FIRST MOV SP, #STK_TM MOV, =0 ALL MAIN O HEAP RESDO 100 STK_TM EQU $ HEAP STK_TM SP MAIN PUSH MOV, SP IN 10 push the second argument IN 10 push the first argument ALL ADD_TWO ADD SP, =4 adjust SP OUT 12 MOV RET SP,
ADD_TWO PUSH MOV, SP SU SP, =2 for the local auto variable tmp PUSH PUSH MOV,%4 get the first argument ADD,%6 get the second argument MOV, store the result to tmp MOV A, return the result via A register MOV RET END SP, FIRST 각함수에서는시작할때모든 register 를 save 하였다가끝날때다시 restore 함으로서함수안에서 register 의사용을자유롭게한다. 그런데, SP 는 activation record 와관련된특수목적이있고, A 는 return value 를담기로하였으므로, 만 save/restore 하면된다. 함수안에서 A,, SP register 를임시로사용할때는극도로주의가필요하다.
Activation Record. SP P for add_two Return Addr to main sum i P for main Return Addr to FIRST P for first (null) P 각함수호출을위한 activation record 는현재의 register 가가리키는곳에서시작한다. 따라서호출된함수를위한 argument 들은바로아래에저장된 Return Address 를감안할때 %4, %6. %8 순으로저장되어있다., %-4, 등위쪽은 local auto variable 을위한공간이다. 이 auto variable 들은함수가 return 될때 "MOV SP, " 에의해서소멸되어버린다. 그리고 local auto variable 위의공간은 register 를 save 하는등의임시목적으로활용된다. temporary location.. local auto variables.. previous P return address urrent P arguments 각 activation record 의 ase 들은 register 를시작으로하여 linked list 를형성하여함수가 return 된후에돌아갈환경을기억하고있다. 각함수를호출하기전에는그함수를위한 argument 를역순으로 stack 에 push 하여전달하고 return 값은 A register 를통해서전달한다. Return 된후에는 Stack Pointer 를조정하여 push 된 argument 를제거한다.
Local auto variable 의 memory allocation 새로운 activation record 를준비한다. SP tmp P old P Return Addr argument 1 %4 argument 2 %6 urrent activation record ADD_TWO PUSH SNAP11 MOV, SP SNAP12 SU SP, =2 for the local auto variable tmp SNAP13 PUSH PUSH 사용된 activation record 를제거한다. Argument 는그대로남아있으므로 return 된후 SP 를 adjust 하여제거한다. MOV,%4 get the first argument ADD,%6 get the second argument MOV, store the result to tmp MOV A, return the result via A register MOV SP, SNAP14 SNAP15 RET SP P tmp old P Return Addr argument 1 argument 2 another old P urrent activation record
앞의 ADD_TWO 를다음과같이호출한다면 // x = add_two(1,2); MOV A, =2 push the second argument SNAP1 MOV A, =1 push the first argument SNAP2 ALL ADD_TWO SNAP3 ADD SP, =4 adjust SP to remove arguments SNAP4 At SNAP1 (push the second argument) SP: 2 : %4 At SNAP2 (push the first argument) 1 SP: 2 : %4
At ADD_TWO (after ALL ADD_TWO) ALL 에의해 push 됨 1 SP: 2 : %4 At SNAP11 (after PUSH ) 1 SP: 2 : %4 이전 activation record 를기억하기위함
At SNAP12 (after MOV, SP) 1 %4 SP: 2 %6 activation record 새로형성됨 가 : At SNAP13 (after SU SP, =2) local auto variable tmp 1 %4 새로형성된 activation SP: 2 %6 record 에 local variable 을위한공간을만듬 :
At SNAP14 (after MOV SP, ) tmp is removed 1 %4 우선 local variable 들을 SP: 2 %6 제거함 : At SNAP15 (after ) 1 SP: 2 : %4 Pop 을통해서이전 activation record 로돌아감아직 return address 와 argument 들은남아있음
At SNAP3 (after RET) 1 SP: 2 : Return addr is poped %4 RET 에의해서 이 pop 되므로 SP 가한칸아래를가리킴을주의할것 At SNAP4 (after ADD SP, =4) 1 SP: 2 : %4 Arguments are removed. 최종적으로 argument 들을 stack 에서제거하여 top 에있던 activation record 를완전히제거함
여러가지함수의호출 /* A example of three function calls */ // argument 는없고 local auto variable 이 2 개 int func_one() { int a=1; int b=2; return fun_two(a,b,3) + 4; } // 3 개의 argument int func_two(int x, int y, int z) { return func_three(x+y,z)+5; } SP a %-4 b P Old P Local variable a,b 는각각 %-4, 로 reference 된다. P,SP Old P x %4 y %6 z %8 // 2 개의 argumrnt 와 2 개의 local variable int func_three(int x, int y) { int a=6; int b; b = x+y; return a+b; } main() { int r; r = func_one(); put_int(r); } Argument x,y,z 는각각 %4,%6,%8 로 reference 된다. SP a %-4 b P Old P x %4 y %6 Argument x,y 는 %4,%6 으로 local variable a,b 는 %-4, 로 reference 된다.
THREE START 0 USE TET FIRST MOV SP, #STK_TM MOV, =0 ALL MAIN 0 O USE DATA USE SS USE STAK HEAP RESO 500 STK_TM EQU $ MAIN SNAP1 PUSH MOV, SP SU SP, =2 int r; PUSH PUSH save registers SNAP1-2 ALL FUN_ONE MOV, A r = func_one(); MOV A, ALL PUT_INT put_print(r); ADD SP, =2 SP r of main 0 0 SP 0 0 FUN_ONE 의 argument 가아니라 temporary location 으로사용한것임 r of main restore registers MOV RET SP,
FUN_ONE SNAP2 PUSH MOV, SP SU SP, =4 int a; int b; PUSH PUSH MOV A, =1 MOV %-4, A a=1; MOV A, =2 MOV, A b=2; SP %-4 a of func_one b of func_one r of main 0 0 MOV A, =3 push 3 MOV A, push b MOV A, %-4 push a ALL FUN_TWO 2 ADD SP, =6 ADD A, =4 MOV RET SP,
FUN_TWO SNAP3 PUSH MOV, SP PUSH PUSH MOV A, %8 push z MOV A, %4 ADD A, %6 push x+y ALL FUN_THREE 3 SNAP6 ADD SP, =4 SNAP7 ADD A, =5,SP Old 2 1(a) %4 x of func_two 2(b) %6 y of func_two 3 %8 z of func_two 1 a of func_one 2 b of func_one Old r of main 0 0 MOV RET SP, SP Old 2 1(a) %4 x of func_two 2(b) %6 y of func_two 3 %8 z of func_two 1 a of func_one 2 b of func_one Old r of main 0 0 SP 3(x+y) x of func three 3(z) y of func_three Old 2 1(a) %4 x of func_two 2(b) %6 y of func_two 3 %8 z of func_two 1 a of func_one 2 b of func_one Old r of main 0 0
FUN_THREE PUSH MOV, SP SU SP, =4 int a; int b; SNAP4 PUSH PUSH SNAP5 MOV A, =6 MOV %-4, A a=6; MOV A, %4 x ADD A, %6 +y MOV, A b = x+y; MOV A, %-4 ADD A, a+b MOV RET SP, SP %-4 a of func_three b of func_three Old 3 3(x+y) %4 x of func three 3(z) %6 y of func_three Old 2 1(a) x of func_two 2(b) y of func_two 3 z of func_two 1 a of func_one 2 b of func_one Old r of main 0 0 USE DATA LTORG END FIRST SP 3 3(x+y) x of func three 3(z) y of func_three Old 2 1(a) %4 x of func_two 2(b) %6 y of func_two 3 %8 z of func_two 1 a of func_one 2 b of func_one Old r of main 0 0