231 Fall 2008 -- Exam 3 (with answers) Name: ______________________ Consider these terms -- .align, .asciz, .bss, .global, heap, mov, restore, .rodata, save, set, .skip, stack, .text, .word, %i0, %o0. Fill in the blanks in 1-10 with the best term. (2 pts. each) 1. .section "__.text__" 2. __.global__ main 3. main: ___save___ %sp,-120,%sp st %g0, [%fp-20] ! %fp-20 is a reference to a local 4. ! variable in the __stack__ frame mov 4, %o0 call malloc nop 5. ___mov____ %o0, %l0 st %g0, [%l0] ! %l0 points to a dynamic variable in 6. ! the __heap__ ... ld [%l0], %l1 ld [%fp-20], %l2 add %l1, %l2, %o1 7. ___set____ fmt, %o0 call printf nop mov %g0, %i0 ret 8. __restore__ 9. .section "__.rodata__" 10. fmt: __.asciz__ "%d\n" Consider this program int a = 25; int funny_add( int b, int c ){ a = a + 10; b = b + 20; c = c + 30; return( a + b + c ); } void main(void){ int d = 40, e; e = funny_add( a, d ); } Show final value after calls to funny_add() for the variables listed below, by column, according to the specified parameter passing methods. (18 pts.) b:call by value b:call by value-result b:call by reference c:call by value c:call by value-result c:call by reference 11. a __35__ __45__ __55__ 12. d __40__ __70__ __70__ 13. e _150__ _150__ _180__ 14. Fill in the blanks for generic subroutine actions. (2 pts. per blank) caller: push parameter2 on stack push parameter1 on stack call subroutine /* pushes return address onto the stack */ subroutine: /* callee save */ push __registers__ to save push old fp set new __fp__ as current __sp__ subtract from __sp__ to make room for locals set __sp__ to current __fp__ pop __fp____________________ pop __registers__ to restore return /* pops return address from stack */ clean parameters off stack 15. Identify the five items in a generic stack frame (10 pts.) parameters return address registers to save old fp local variables 16. Fill in the body of the SPARC assembly language program so that it accomplishes the function indicated by the C code in the comments. (6 pts.) ! int sum( int a, int b ){ ! return( a + b ); ! } sum: save %sp, -96, %sp __add___%i0,_%i1,_%i0__ ret restore 17. Give SPARC code for _one_ of the swap procedures below. Optimized code as given in the notes is acceptable; unoptimized code is also acceptable. (15 pts.) void swap1( int *x, int *y ){ int temp; temp = *x; *x = *y; *y = temp; } // or -- POSSIBLE ANSWER -- void swap2( int *x, int *y ){ .global swap register int temp1, temp2; swap: temp1 = *x; ld [%o0], %g1 temp2 = *y; ld [%o1], %g2 *x = temp2; st %g2, [%o0] *y = temp1; st %g1, [%o1] } retl nop 18. Give the SPARC code for the following subroutine. (15 pts.) void prt( int *a, int n ){ register int i; for( i = 0; i < n; i++ ){ printf( "%d\n", a[i] ); } } -- POSSIBLE ANSWER -- define(base_r,l0) define(offset_r,l1) define(i_r,l2) define(count_r,l3) .global prt prt: save %sp, -96, %sp mov %i0, %base_r mov %i1, %count_r clr %i_r loop: cmp %i_r, %count_r bge done nop sll %i_r, 2, %offset_r ld [ %base_r + %offset_r ], %o1 set fmt, %o0 call printf nop inc %i_r ba loop nop done: ret restore .section ".rodata" fmt: .asciz "%d\n" XC-1. Consider the following program c01: int test( int a ){ c02: int b; c03: return( &a - &b ); c04: } c05: c06: int main(){ c07: printf( "ptr diff is %d bytes\n", test( 1 ) * sizeof( int ) ); c08: return 0; c09: } and the generated assembly code s01: test: s02: save %sp,-120, %sp s03: st %i0, [%fp+68] s04: add %fp, 68, %g2 s05: add %fp, -20, %g1 s06: sub %g2, %g1, %g1 s07: sra %g1, 2, %g1 s08: mov %g1, %i0 s09: restore s10: jmp %o7+8 s11: nop (a) What does the test() subroutine do so that &a is a legal operation on input parameter a? (2 pts.) places the value in the allocated entry of the stack (at %fp+68) (b) What are the boundaries for the stack frame for test() in terms of the registers %sp and %fp? Is %fp+68 in the stack frame for test() or the one for main()? (4 pts.) +--------+ %sp -->| stack | | frame | | for | | test() | +--------+ %fp -->| stack | | frame | | for |<-- %fp + 68 | main() | +--------+ (c) Why does test() perform the sra instruction on line s07? (2 pts.) pointer arithmetic in C is in terms of data type units, and sizeof(int) is 4 bytes; sra is equivalent here to dividing the calculated byte count by 4 (d) Is the instruction in s10 equivalent to ret, retl, or neither one? Explain. (2 pts.) retl (since retl is defined as jmpl %o7+8,%g0); the restore takes effect before the jmp is reached and so jmp cannot use %i7+8