160 likes | 283 Views
15-213 Recitation 2 – 2/11/02. Outline Stacks & Procedures Homogenous Data Arrays Nested Arrays. Mengzhi Wang e-mail: mzwang@cs.cmu.edu Office Hours: Thursday 1:30 – 3:00 Wean Hall 3108. Reminders Lab 2: Tuesday, 11:59. Stacks. Grows down
E N D
15-213 Recitation 2 – 2/11/02 Outline • Stacks & Procedures • Homogenous Data • Arrays • Nested Arrays Mengzhi Wang e-mail: mzwang@cs.cmu.edu Office Hours: Thursday 1:30 – 3:00 Wean Hall 3108 • Reminders • Lab 2: Tuesday, 11:59
Stacks • Grows down • Stores local variables that can’t fit in registers • Stores arguments and return addresses • %esp Stack Pointer • Points to the top value on the stack • %ebp Base Pointer • Points to a function’s stack frame • pushl • Decrements, then places value • popl • ‘Returns’ value, then increments
Frame Pointer (%ebp) Stack Frames Caller Frame • Abstract partitioning of the stack • Each Frame contains the state for a single function instant Arguments Return Addr Old %ebp Saved Registers Local Variables Argument Build Stack Pointer (%esp)
Procedures call: Caller Responsibilities • Arguments (pushl) • In what order? • Return Address (done by call) ret: Callee Responsibilities • Save Registers (especially %ebp) • Set up Stack Frame • Return value in %eax
Problem 1: Call Chain void absdiff(int *result, int x, int y) { int z; if (x >= y) z = x - y; else z = y - x; *result = z; return; } int main() { int result; int x,y; x = 5; y = -3; absdiff(&result, x, y); printf("|(%d) - (%d)| = %d\n", x, y, result); return 0; }
Problem 1: Call Chain <main>: push %ebp mov %esp,%ebp sub $0x18,%esp movl $0x5,-8(%ebp) movl $0xfffffffd, -12(%ebp) add $0xfffffffc,%esp mov -12(%ebp),%eax push %eax mov -8(%ebp),%eax push %eax lea -4(%ebp),%eax push %eax call <absdiff> add $0x10, %esp mov -4(%ebp),%eax push %eax mov -12(%ebp),%eax push %eax mov -8(%ebp),%eax push %eax push $0x80484d8 call <printf> mov %ebp,%esp pop %ebp ret <absdiff>: push %ebp mov %esp,%ebp sub $0x18,%esp mov 0xc(%ebp),%eax cmp 0x10(%ebp),%eax jl .L1 mov 0xc(%ebp),%eax mov 0x10(%ebp),%edx mov %eax,%ecx sub %edx,%ecx jmp .L2 .L1 mov 0x10(%ebp),%eax mov 0xc(%ebp),%edx mov %eax,%ecx sub %edx,%ecx .L2 mov 0x8(%ebp),%eax mov %ecx,(%eax) mov %ebp,%esp pop %ebp ret
Problem 1: Answer Old %ebp %ebp <main>: push %ebp mov %esp,%ebp sub $0x18,%esp movl $0x5,-8(%ebp) movl $0xfffffffd, -12(%ebp) add $0xfffffffc,%esp mov -12(%ebp),%eax push %eax mov -8(%ebp),%eax push %eax lea -4(%ebp),%eax push %eax call <absdiff> result x = 5 y = -3 %esp -3 5 &result Rtn Address %esp
Problem 1: Answer <absdiff>: push %ebp mov %esp,%ebp sub $0x18,%esp mov 0xc(%ebp),%eax cmp 0x10(%ebp),%eax jl .L1 mov 0xc(%ebp),%eax mov 0x10(%ebp),%edx mov %eax,%ecx sub %edx,%ecx jmp .L2 .L1 mov 0x10(%ebp),%eax mov 0xc(%ebp),%edx mov %eax,%ecx sub %edx,%ecx .L2 mov 0x8(%ebp),%eax mov %ecx,(%eax) mov %ebp,%esp pop %ebp ret * * * %esp -3 5 &result Rtn Address Old %ebp %ebp %esp
Problem 1: Answer Old %ebp %ebp %esp <main>: ….. add $0x10, %esp mov -4(%ebp),%eax push %eax mov -12(%ebp),%eax push %eax mov -8(%ebp),%eax push %eax push $0x80484d8 call <printf> mov %ebp,%esp pop %ebp ret result 5 -3 %esp result -3 5 0x80484d8 Rtn Address
Problem 2: Recursion With the following code, what does the stack look like if we call fib(2, 1, 0) and reach the point where if(n==0) holds true? int fib(int n, int next, int result) { if(n == 0) return result; return fib(n - 1, next + result, next); }
Problem 2: Answer 0 ; third argument to fib 1 ; second 2 ; first ret ; call fib(2,1,0) oldebp ; <--- ebp of fib’s caller 1 ; <--- push next 1 ; <--- next + result 1 ; <--- n - 1 ret ; call fib (1, 1, 1) oldebp ; <--- ebp of fib’s 2 ; <--- push next 3 ; <--- push next + result 0 ; <--- push n-1 ret ; call fib (0, 3, 2)
Homogenous Data: Arrays • Allocated as contiguous blocks of memory Address Computation Examples • int cmu[5] = {…} • cmu begins at memory address 40 cmu[0] 40 + 4*0 = 40 cmu[3] 40 + 4*3 = 52 cmu[-1] 40 + 4*-1 = 36 cmu[15] 40 + 4*15 = 100
Problem 3: Arrays get_sum: pushl %ebp movl %esp,%ebp pushl %ebx movl 8(%ebp),%ebx # ebx = 1st arg movl 12(%ebp),%ecx # ecx = 2nd arg xorl %eax,%eax # eax = 0 movl %eax,%edx # edx = 0 cmpl %ecx,%eax # jge .L4 # if (ecx >= 0) goto L4 .L6: addl (%ebx,%edx,4),%eax # eax += Mem[ebx+edx*4] incl %edx # edx ++ cmpl %ecx,%edx # jl .L6 # if (edx < ecx) goto L6 .L4: popl %ebx movl %ebp,%esp popl %ebp ret
Problem 3: Answer get_sum: pushl %ebp movl %esp,%ebp pushl %ebx movl 8(%ebp),%ebx movl 12(%ebp),%ecx xorl %eax,%eax movl %eax,%edx cmpl %ecx,%eax jge .L4 .L6: addl (%ebx,%edx,4),%eax incl %edx cmpl %ecx,%edx jl .L6 .L4: popl %ebx movl %ebp,%esp popl %ebp ret int get_sum(int * array, int size) { int sum = 0; int i=0; for (i=0; i<size; i++) sum += array[i]; return sum; }
Problem 4: Nested arrays int main(int argc, char **argv) { int i,j,r=0; for (i=0; i<argc; i++) { j=0; while(argv[i][j] != '\0') { r ^= argv[i][j]; j++; } } return r; }
Problem 4: Answer .L9: movsbl (%ecx,%edx),%eax xorl %eax,%esi incl %ecx cmpb $0,(%ecx,%edx) jne .L9 .L5: incl %ebx cmpl 8(%ebp),%ebx jl .L6 .L4: movl %esi,%eax popl %ebx popl %esi popl %edi movl %ebp,%esp popl %ebp ret main: pushl %ebp movl %esp,%ebp pushl %edi pushl %esi pushl %ebx movl 12(%ebp),%edi xorl %esi,%esi xorl %ebx,%ebx cmpl 8(%ebp),%esi jge .L4 .L6: xorl %ecx,%ecx movl (%edi,%ebx,4),%eax cmpb $0,(%eax) je .L5 movl %eax,%edx