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.