简体   繁体   中英

how stack differs in 32 bit and 64 bit processors

i disassembled the following code in gdb for both 32 bit and 64 bit intel processors.

void main() {
5      char *args[2];
6   
7      args[0] = "/bin/sh";
8      args[1] = NULL;
9      execve(args[0],args,NULL);
10     exit(0);
11  }

Following are the assembly code generated.

For 64 bit

Dump of assembler code for function main:
   0x000000000040105e <+0>: push   %rbp
   0x000000000040105f <+1>: mov    %rsp,%rbp
   0x0000000000401062 <+4>: sub    $0x10,%rsp
   0x0000000000401066 <+8>: movq   $0x493564,-0x10(%rbp) ; <- this line
   0x000000000040106e <+16>:    movq   $0x0,-0x8(%rbp)
   0x0000000000401076 <+24>:    mov    -0x10(%rbp),%rax
   0x000000000040107a <+28>:    lea    -0x10(%rbp),%rcx
   0x000000000040107e <+32>:    mov    $0x0,%edx
   0x0000000000401083 <+37>:    mov    %rcx,%rsi
   0x0000000000401086 <+40>:    mov    %rax,%rdi
   0x0000000000401089 <+43>:    callq  0x433510 <execve>
   0x000000000040108e <+48>:    mov    $0x0,%edi
   0x0000000000401093 <+53>:    callq  0x407560 <exit>

For 32 bit

Dump of assembler code for function main:
0x8000130 <main>:       pushl  %ebp
0x8000131 <main+1>:     movl   %esp,%ebp
0x8000133 <main+3>:     subl   $0x8,%esp
0x8000136 <main+6>:     movl   $0x80027b8,0xfffffff8(%ebp) ; <- this line
0x800013d <main+13>:    movl   $0x0,0xfffffffc(%ebp)
0x8000144 <main+20>:    pushl  $0x0
0x8000146 <main+22>:    leal   0xfffffff8(%ebp),%eax
0x8000149 <main+25>:    pushl  %eax
0x800014a <main+26>:    movl   0xfffffff8(%ebp),%eax
0x800014d <main+29>:    pushl  %eax
0x800014e <main+30>:    call   0x80002bc <__execve>
0x8000153 <main+35>:    addl   $0xc,%esp
0x8000156 <main+38>:    movl   %ebp,%esp
0x8000158 <main+40>:    popl   %ebp
0x8000159 <main+41>:    ret
End of assembler dump.

In above the assembly code which i have marked is where i have not understood. 64 bit system declares 16 bits(bits, bytes or word which i want to learn) offset from rbp while 32 bit system declares 8 bits offset from ebp. Can someone explain the difference of how stack pointer advances in both 32 bit and 64 bit system and what unit it is (bits,bytes or word).

char * args[2];

Is an array of two pointers. On 32-bit machines, pointers (addresses, but not necessarily) are 32 bits wide, and on 64-bit machines, pointers (and never addresses) are 64 bits wide.

That means, that the area on the stack in the current stack frame must be 2 * pointer_width , which makes 8 for 32-bit machines, and 16 for 64-bit machines.

Below in your code you can see

movl   $0x80027b8, -0x8(%ebp)
movl   $0x0, -0x4(%ebp)

... a movement 32-bit dwords to the pointers (one address of the string, and one NULL ).

On the other hand, 64-bit code requires two dwords (8 bytes) for storing the address.

movq   $0x0, -0x8(%rbp)
movq   $0x493564, -0x10(%rbp)

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