简体   繁体   中英

Using the command 'x/20x $esp' in GDB, how does the stack work?

I wrote a simple program in C to be analysed in GDB

#include <stdio.h>

int add_numbers(int n1,int n2)
{
    int sum=n1+n2;
    return sum;
}

int main()
{
        int n1=1;
        int n2=2;
        int sum;

        sum = add_numbers(n1,n2);
        printf("The sum of 1 and 2 is %d",sum);

        return 0;
}    

Here is the disassembly of main

0x08048433 <+0>:    push   %ebp
0x08048434 <+1>:    mov    %esp,%ebp
0x08048436 <+3>:    and    $0xfffffff0,%esp
0x08048439 <+6>:    sub    $0x20,%esp
0x0804843c <+9>:    movl   $0x1,0x14(%esp)
0x08048444 <+17>:   movl   $0x2,0x18(%esp)
0x0804844c <+25>:   mov    0x18(%esp),%eax
0x08048450 <+29>:   mov    %eax,0x4(%esp)
0x08048454 <+33>:   mov    0x14(%esp),%eax
0x08048458 <+37>:   mov    %eax,(%esp)
0x0804845b <+40>:   call   0x804841d <add_numbers>
0x08048460 <+45>:   mov    %eax,0x1c(%esp)
0x08048464 <+49>:   mov    0x1c(%esp),%eax
0x08048468 <+53>:   mov    %eax,0x4(%esp)
0x0804846c <+57>:   movl   $0x8048510,(%esp)
0x08048473 <+64>:   call   0x80482f0 <printf@plt>
0x08048478 <+69>:   mov    $0x0,%eax
0x0804847d <+74>:   leave  
0x0804847e <+75>:   ret    

I then set a breakpoint on line 12 and analysed the stack with 'x/20x $esp'

0xbffff270: 0x00000001  0xbffff334  0xbffff33c  0xb7e4342d
0xbffff280: 0xb7fbb3c4  0x00000001  0x0804848b  0xb7fbb000
0xbffff290: 0x08048480  0x00000000  0x00000000  0xb7e29a83
0xbffff2a0: 0x00000001  0xbffff334  0xbffff33c  0xb7feccea
0xbffff2b0: 0x00000001  0xbffff334  0xbffff2d4  0x0804a014

So why is it that the statement 'movl $0x1,0x14(%esp)' moves 1 to the second address in the stack? Specifically how is this stack incremented(or decremented because the stack grows down?) to put '1' in the address following the'$eip' register?

A tutorial would be nice too since I've probably missed this information. Thanks!

-Tom

The assembly instruction movl $0x1,0x14(%esp) moves the 32-bit integer value 1 into the 4 bytes located 20 bytes past the address that the register ESP points to. In your memory dump that would be the four bytes starting at 0xbffff284 , which is the second 32-bit value on the second line.

This instruction doesn't change the value of ESP. It's neither incremented nor decremented. The value in ESP changed previously by the instruction at 0x08048439 : sub $0x20,%esp . This instruction reserves 32-bytes on the stack for local variables used by the function, along with outgoing arguments for function calls. The variables n1 , n2 , and sum are located at addresses 0xbffff284 , 0xbffff288 , and 0xbffff28c respectively.

Nothing is stored at the address following EIP anywhere in your program. I assume you actually meant something else by this, but I don't know what.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM