C P R O G R A M ( f o u r t h _ p r o g . c ) #include int Func1(int x); int Func2(int x); int Func3(int x); int Func4(int x); int main() { int A = 3; int B = 5; int C; C = A + B; C = Func1(C); C = C + 1; return 2; } int Func1(int x) { return Func2(x) + 1; } int Func2(int x) { return Func3(x) + 1; } int Func3(int x) { return Func4(x) + 1; } int Func4(int x) { return x + 1; } C O M P I L E D P R O G R A M ( f o u r t h _ p r o g . a s m ) : .Orig x3000 ; R7 saved PC, R6 StkPtr, R5 FramePtr, R4 GlobalStkPtr INIT_CODE LEA R6, #-1 ; set StkPtr = xEFFF ADD R5, R6, #0 ADD R6, R6, R6 ADD R6, R6, R6 ADD R6, R6, R5 ADD R6, R6, #-1 ADD R5, R5, R5 ; ? (oops! "no harm" error) ADD R5, R6, #0 ; set FramePtr = xEFFF LD R4, GLOBAL_DATA_POINTER ; set GlobalStkPtr = "GLOBAL_DATA_START" LD R7, GLOBAL_MAIN_POINTER ; load R7 with address of "main" jsrr R7 ; begin "main" HALT GLOBAL_DATA_POINTER .FILL GLOBAL_DATA_START GLOBAL_MAIN_POINTER .FILL main ;;;;;;;;;;;;;;;;;;;;;;;;;;;;main;;;;;;;;;;;;;;;;;;;;;;;;;;;; main ADD R6, R6, #-2 ; PUSH space for return value STR R7, R6, #0 ; PUSH R7 (addr of HALT) ADD R6, R6, #-1 ; PUSH FramePtr STR R5, R6, #0 ADD R5, R6, #-1 ; create new FramePtr ADD R6, R6, #-3 ; PUSH space for 3 local variables (A, B, & C) ADD R7, R4, #14 ; get A=3 (L2) from GlobalStkPtr+14, str at FramePtr-1 ldr R7, R7, #0 str R7, R5, #-1 ADD R7, R4, #12 ; get B=5 (L3) from GlobalStkPtr+12, str at FramePtr-2 ldr R7, R7, #0 str R7, R5, #-2 ldr R7, R5, #-1 ; A+B and str into FramePtr ldr R3, R5, #-2 add R7, R7, R3 str R7, R5, #0 ldr R7, R5, #0 ; PUSH A+B (pass parameter for Func1) ADD R6, R6, #-1 STR R7, R6, #0 ADD R0, R4, #1 ; jsrr Func1 LDR R0, R0, #0 jsrr R0 LDR R7, R6, #0 ; POP return value from Func1 ADD R6, R6, #1 str R7, R5, #0 ; str return value at FramePtr (C) ldr R7, R5, #0 ; C = C + 1 ADD R3, R4, #13 ldr R3, R3, #0 add R7, R7, R3 str R7, R5, #0 ADD R7, R4, #11 ; ld return value = 2 ldr R7, R7, #0 lc3_L1_second_prog STR R7, R5, #3 ADD R6, R5, #1 ; POP local variables (A,B,C) LDR R5, R6, #0 ; POP last FramePtr ADD R6, R6, #1 LDR R7, R6, #0 ; POP last R7 (Addr of HALT) ADD R6, R6, #1 RET ; return to HALT ;;;;;;;;;;;;;;;;;;;;;;;;;;;;Func1;;;;;;;;;;;;;;;;;;;;;;;;;;;; lc3_Func1 ADD R6, R6, #-2 ; PUSH for Func 1 return value, PUSH R7 (saved PC) STR R7, R6, #0 ADD R6, R6, #-1 ; PUSH R5 (FramePtr) STR R5, R6, #0 ADD R5, R6, #-1 ; create Func1 FramePtr ADD R6, R6, #-1 ; get C (Passed parameter from main) ldr R7, R5, #4 ADD R6, R6, #-1 ; PUSH C (pass parameter for Func2) STR R7, R6, #0 ADD R0, R4, #3 ; jsrr Func2 LDR R0, R0, #0 jsrr R0 LDR R7, R6, #0 ; POP return value from Func2 ADD R6, R6, #1 ADD R3, R4, #13 ; ld return value (C+1) for main ldr R3, R3, #0 add R7, R7, R3 lc3_L6_second_prog STR R7, R5, #3 ADD R6, R5, #1 ; POP R5 (FramePtr) LDR R5, R6, #0 ADD R6, R6, #1 LDR R7, R6, #0 ; POP R7 (saved PC) ADD R6, R6, #1 RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;Func2;;;;;;;;;;;;;;;;;;;;;;;;;;;; lc3_Func2 ADD R6, R6, #-2 ; PUSH for Func 2 return value, PUSH R7 (saved PC) STR R7, R6, #0 ADD R6, R6, #-1 ; PUSH R5 (FramePtr) STR R5, R6, #0 ADD R5, R6, #-1 ; create Func2 FramePtr ADD R6, R6, #-1 ; get C (passed parameter from Func1) ldr R7, R5, #4 ADD R6, R6, #-1 ; PUSH C (pass parameter for Func3) STR R7, R6, #0 ADD R0, R4, #5 ; jsrr Func3 LDR R0, R0, #0 jsrr R0 LDR R7, R6, #0 ; POP return value from Func3 ADD R6, R6, #1 ADD R3, R4, #13 ; ld return value (C+1) for Func1 ldr R3, R3, #0 add R7, R7, R3 lc3_L7_second_prog STR R7, R5, #3 ADD R6, R5, #1 ; POP R5 (FramePtr) LDR R5, R6, #0 ADD R6, R6, #1 LDR R7, R6, #0 : POP R7 (saved PC) ADD R6, R6, #1 RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;Func3;;;;;;;;;;;;;;;;;;;;;;;;;;;; lc3_Func3 ADD R6, R6, #-2 ; PUSH for Func3 return value, PUSH R7 (saved PC) STR R7, R6, #0 ADD R6, R6, #-1 ; PUSH R5 (FramePtr) STR R5, R6, #0 ADD R5, R6, #-1 ; create Func3 FramePtr ADD R6, R6, #-1 ; get C (passed parameter from Func2) ldr R7, R5, #4 ADD R6, R6, #-1 ; PUSH C (pass parameter for Func4) STR R7, R6, #0 ADD R0, R4, #7 ; jsrr Func4 LDR R0, R0, #0 jsrr R0 LDR R7, R6, #0 ; POP return value from Func4 ADD R6, R6, #1 ADD R3, R4, #13 ; ld return value (C+1) for Func2 ldr R3, R3, #0 add R7, R7, R3 lc3_L8_second_prog STR R7, R5, #3 ADD R6, R5, #1 ; POP R5 (FramePtr) LDR R5, R6, #0 ADD R6, R6, #1 LDR R7, R6, #0 ; POP R7 (saved PC) ADD R6, R6, #1 RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;Func4;;;;;;;;;;;;;;;;;;;;;;;;;;;; lc3_Func4 ADD R6, R6, #-2 ; PUSH Func4 return value, PUSH R7 (saved PC) STR R7, R6, #0 ADD R6, R6, #-1 ; PUSH R5 (FramePtr) STR R5, R6, #0 ADD R5, R6, #-1 ; create Func4 FramePtr ADD R6, R6, #-1 ; get C (passed paramter from Func3) ldr R7, R5, #4 ADD R3, R4, #13 ; ld return value (C+1) for Func3 ldr R3, R3, #0 add R7, R7, R3 lc3_L9_second_prog STR R7, R5, #3 ADD R6, R5, #1 ; POP R5 (FramePtr) LDR R5, R6, #0 ADD R6, R6, #1 LDR R7, R6, #0 ; POP R7 (saved PC) ADD R6, R6, #1 RET ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; void scanf(const char *format, ...) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SCANF_PERCENT .FILL -37 SCANF_C .FILL -99 SCANF_D .FILL -100 SCANF_S .FILL -115 SCANF_0 .FILL -48 SCANF_9 .FILL -57 SCANF_MINUS .FILL -45 SCANF_BUF .BLKW 6 lc3_scanf ; remainder of scanf not included ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ; void printf(const char *format, ...) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; PRINTF_PERCENT .FILL -37 PRINTF_C .FILL -99 PRINTF_D .FILL -100 PRINTF_S .FILL -115 PRINTF_B .FILL -98 PRINTF_O .FILL -111 PRINTF_X .FILL -120 PRINTF_ASCII .FILL 48 ;postive ascii value of '0' .FILL 49 .FILL 50 .FILL 51 .FILL 52 .FILL 53 .FILL 54 .FILL 55 .FILL 56 .FILL 57 .FILL 65 ;A .FILL 66 .FILL 67 .FILL 68 .FILL 69 .FILL 70 PRINTF_MINUS .FILL 45 PRINTF_BUF .BLKW 18 lc3_printf ; remainder of printf not included GLOBAL_DATA_START L1_second_prog .FILL lc3_L1_second_prog ; FramePtr Func1 .FILL lc3_Func1 ; +1 L6_second_prog .FILL lc3_L6_second_prog ; +2 Func2 .FILL lc3_Func2 ; +3 L7_second_prog .FILL lc3_L7_second_prog ; +4 Func3 .FILL lc3_Func3 ; +5 L8_second_prog .FILL lc3_L8_second_prog ; +6 Func4 .FILL lc3_Func4 ; +7 L9_second_prog .FILL lc3_L9_second_prog ; +8 scanf .FILL lc3_scanf ; +9 printf .FILL lc3_printf ; +10 L5_second_prog .FILL #2 ; +11 L3_second_prog .FILL #5 ; +12 L4_second_prog .FILL #1 ; +13 L2_second_prog .FILL #3 ; +14 .END S T A C K S N A P S H O T S : Stk at main: xEFF9 xEFFA xEFFB xEFFC FramePtr (xEFFF) xEFFD R7 (x300B) xEFFE return value space xEFFF <- StkPtr <- FramePtr (initially) Stk before call Func1: xEFF5 xEFF6 xEFF7 xEFF8 pass value to Func1 (C = 8) xEFF9 B = 5 xEFFA A = 3 xEFFB C = 8 (main local var) <- FramePtr (main) xEFFC FramePtr (xEFFF) xEFFD R7 (x300B) xEFFE return value space xEFFF <- StkPtr <- FramePtr (initially) Stk before call Func2: xEFF0 xEFF1 xEFF2 xEFF3 pass value to Func2 (C = 8) xEFF4 (Func1 local var) <- FramePtr (Func1) xEFF5 R5 FramePtr (xEFFB) xEFF6 R7 Saved PC (x3024) xEFF7 return value from Func1 space xEFF8 pass value to Func1 (C = 8) xEFF9 B = 5 xEFFA A = 3 xEFFB C = 8 (main local var) <- FramePtr (main) xEFFC R5 FramePtr (xEFFF) xEFFD R7 Saved PC (x300B) xEFFE return value from main space xEFFF <- StkPtr <- FramePtr (initially) Stk before call Func3: xEFEB xEFEC xEFED xEFEE pass value to Func3 (C = 8) xEFEF (Func2 local var) <- FramePtr (Func2) xEFF0 R5 FramePtr (xEFF4) xEFF1 R7 Saved PC (x3041) xEFF2 return value from Func2 space xEFF3 pass value to Func2 (C = 8) xEFF4 (Func1 local var) <- FramePtr (Func1) xEFF5 R5 FramePtr (xEFFB) xEFF6 R7 Saved PC (x3024) xEFF7 return value from Func1 space xEFF8 pass value to Func1 (C = 8) xEFF9 B = 5 xEFFA A = 3 xEFFB C = 8 (main local var) <- FramePtr (main) xEFFC R5 FramePtr (xEFFF) xEFFD R7 Saved PC (x300B) xEFFE return value from main space xEFFF <- StkPtr <- FramePtr (initially) Stk before call Func4: xEFE6 xEFE7 xEFE8 xEFE9 pass value to Func4 (C = 8) xEFEA (Func3 local var) <- FramePtr (Func3) xEFEB R5 FramePtr (xEFEF) xEFEC R7 Saved PC (x3059) xEFED return value from Func3 space xEFEE pass value to Func3 (C = 8) xEFEF (Func2 local var) <- FramePtr (Func2) xEFF0 R5 FramePtr (xEFF4) xEFF1 R7 Saved PC (x3041) xEFF2 return value from Func2 space xEFF3 pass value to Func2 (C = 8) xEFF4 (Func1 local var) <- FramePtr (Func1) xEFF5 R5 FramePtr (xEFFB) xEFF6 R7 Saved PC (x3024) xEFF7 return value from Func1 space xEFF8 pass value to Func1 (C = 8) xEFF9 B = 5 xEFFA A = 3 xEFFB C = 8 (main local var) <- FramePtr (main) xEFFC R5 FramePtr (xEFFF) xEFFD R7 Saved PC (x300B) xEFFE return value from main space xEFFF <- StkPtr <- FramePtr (initially) Stk in Func4: xEFE2 xEFE3 xEFE4 xEFE5 (Func4 local var) <- FramePtr (Func4) xEFE6 R5 FramePtr (xEFEA) xEFE7 R7 Saved PC (x3071) xEFE8 return value from Func4 = 9 xEFE9 pass value to Func4 (C = 8) xEFEA (Func3 local var) <- FramePtr (Func3) xEFEB R5 FramePtr (xEFEF) xEFEC R7 Saved PC (x3059) xEFED return value from Func3 space xEFEE pass value to Func3 (C = 8) xEFEF (Func2 local var) <- FramePtr (Func2) xEFF0 R5 FramePtr (xEFF4) xEFF1 R7 Saved PC (x3041) xEFF2 return value from Func2 space xEFF3 pass value to Func2 (C = 8) xEFF4 (Func1 local var) <- FramePtr (Func1) xEFF5 R5 FramePtr (xEFFB) xEFF6 R7 Saved PC (x3024) xEFF7 return value from Func1 space xEFF8 pass value to Func1 (C = 8) xEFF9 B = 5 xEFFA A = 3 xEFFB C = 8 (main local var) <- FramePtr (main) xEFFC R5 FramePtr (xEFFF) xEFFD R7 Saved PC (x300B) xEFFE return value from main space xEFFF <- StkPtr <- FramePtr (initially) Stk after return from Func4: xEFE5 xEFE6 xEFE7 xEFE8 return value from Func4 = 9 (C = 9) xEFE9 pass value to Func4 (C = 8) xEFEA (Func3 local var) <- FramePtr (Func3) xEFEB R5 FramePtr (xEFEF) xEFEC R7 Saved PC (x3059) xEFED return value from Func3 space xEFEE pass value to Func3 (C = 8) xEFEF (Func2 local var) <- FramePtr (Func2) xEFF0 R5 FramePtr (xEFF4) xEFF1 R7 Saved PC (x3041) xEFF2 return value from Func2 space xEFF3 pass value to Func2 (C = 8) xEFF4 (Func1 local var) <- FramePtr (Func1) xEFF5 R5 FramePtr (xEFFB) xEFF6 R7 Saved PC (x3024) xEFF7 return value from Func1 space xEFF8 pass value to Func1 (C = 8) xEFF9 B = 5 xEFFA A = 3 xEFFB C = 8 (main local var) <- FramePtr (main) xEFFC R5 FramePtr (xEFFF) xEFFD R7 Saved PC (x300B) xEFFE return value from main space xEFFF <- StkPtr <- FramePtr (initially) Stk after return from Func3: xEFEA xEFEB xEFEC xEFED return value from Func3 = 10 (C = 10) xEFEE pass value to Func3 (C = 8) xEFEF (Func2 local var) <- FramePtr (Func2) xEFF0 R5 FramePtr (xEFF4) xEFF1 R7 Saved PC (x3041) xEFF2 return value from Func2 space xEFF3 pass value to Func2 (C = 8) xEFF4 (Func1 local var) <- FramePtr (Func1) xEFF5 R5 FramePtr (xEFFB) xEFF6 R7 Saved PC (x3024) xEFF7 return value from Func1 space xEFF8 pass value to Func1 (C = 8) xEFF9 B = 5 xEFFA A = 3 xEFFB C = 8 (main local var) <- FramePtr (main) xEFFC R5 FramePtr (xEFFF) xEFFD R7 Saved PC (x300B) xEFFE return value from main space xEFFF <- StkPtr <- FramePtr (initially) Stk after return from Func2: xEFEF xEFF0 xEFF1 xEFF2 return value from Func2 = 11 (C = 11) xEFF3 pass value to Func2 (C = 8) xEFF4 (Func1 local var) <- FramePtr (Func1) xEFF5 R5 FramePtr (xEFFB) xEFF6 R7 Saved PC (x3024) xEFF7 return value from Func1 space xEFF8 pass value to Func1 (C = 8) xEFF9 B = 5 xEFFA A = 3 xEFFB C = 8 (main local var) <- FramePtr (main) xEFFC R5 FramePtr (xEFFF) xEFFD R7 Saved PC (x300B) xEFFE return value from main space xEFFF <- StkPtr <- FramePtr (initially) Stk after return from Func1: xEFF4 xEFF5 xEFF6 xEFF7 return value from Func1 = 12 (C = 12) xEFF8 pass value to Func1 (C = 8) xEFF9 B = 5 xEFFA A = 3 xEFFB C = 8 (main local var) <- FramePtr (main) xEFFC R5 FramePtr (xEFFF) xEFFD R7 Saved PC (x300B) xEFFE return value from main space xEFFF <- StkPtr <- FramePtr (initially) Stk before return from main: xEFF5 xEFF6 xEFF7 xEFF8 pass value to Func1 (C = 8) xEFF9 B = 5 xEFFA A = 3 xEFFB C = 13 (main local var) <- FramePtr (main) xEFFC R5 FramePtr (xEFFF) xEFFD R7 Saved PC (x300B) xEFFE return value from main space xEFFF <- StkPtr <- FramePtr (initially) Stk after return from main: xEFFB xEFFC xEFFD xEFFE return value from main = 2 xEFFF <- StkPtr <- FramePtr (initially)