Upload
jennifer-stevens
View
213
Download
0
Embed Size (px)
Citation preview
15-213 Recitation 2 – 2/11/02
Outline• Stacks & Procedures• Homogenous Data
– Arrays– Nested Arrays
Mengzhi Wang
e-mail:
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
Stack Frames
• Abstract partitioning of the stack
• Each Frame contains the state for a single function instant
Stack Pointer(%esp)
Frame Pointer(%ebp)
Return Addr
SavedRegisters
ArgumentBuild
Old %ebp
LocalVariables
Arguments
CallerFrame
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
<absdiff>:push %ebpmov %esp,%ebpsub $0x18,%espmov 0xc(%ebp),%eaxcmp 0x10(%ebp),%eaxjl .L1 mov 0xc(%ebp),%eaxmov 0x10(%ebp),%edxmov %eax,%ecxsub %edx,%ecxjmp .L2
.L1mov 0x10(%ebp),%eaxmov 0xc(%ebp),%edxmov %eax,%ecxsub %edx,%ecx
.L2mov 0x8(%ebp),%eaxmov %ecx,(%eax)mov %ebp,%esppop %ebpret
<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
Problem 1: Answer
<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>
Old %ebp
result
x = 5
y = -3
%esp
-3
5
&result
Rtn Address %esp
%ebp
Problem 1: Answer<absdiff>:
push %ebpmov %esp,%ebpsub $0x18,%espmov 0xc(%ebp),%eaxcmp 0x10(%ebp),%eaxjl .L1 mov 0xc(%ebp),%eaxmov 0x10(%ebp),%edxmov %eax,%ecxsub %edx,%ecxjmp .L2
.L1mov 0x10(%ebp),%eaxmov 0xc(%ebp),%edxmov %eax,%ecxsub %edx,%ecx
.L2mov 0x8(%ebp),%eaxmov %ecx,(%eax)mov %ebp,%esppop %ebpret
%esp
-3
5
&result
Rtn Address
%ebpOld %ebp
%esp
*
*
*
Problem 1: Answer
<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
Old %ebp
result
5
-3
%esp
result
-3
5
%ebp
0x80484d8
Rtn Address
%esp
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: Answer0 ; third argument to fib1 ; second2 ; firstret ; call fib(2,1,0)oldebp ; <--- ebp of fib’s caller1 ; <--- push next1 ; <--- next + result1 ; <--- n - 1ret ; call fib (1, 1, 1)oldebp ; <--- ebp of fib’s2 ; <--- push next3 ; <--- push next + result0 ; <--- push n-1ret ; 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 = 40cmu[3] 40 + 4*3 = 52cmu[-1] 40 + 4*-1 = 36cmu[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
int get_sum(int * array, int size){ int sum = 0; int i=0; for (i=0; i<size; i++) sum += array[i]; return sum;}
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
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
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
.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