C 32位和64位处理器中堆栈的区别

C 32位和64位处理器中堆栈的区别,c,assembly,gdb,disassembly,C,Assembly,Gdb,Disassembly,我在gdb中为32位和64位intel处理器反汇编了以下代码 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 } 下面是生成的汇编代码 对于64位 Dump of assembler code for function main: 0x000000

我在gdb中为32位和64位intel处理器反汇编了以下代码

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  }
下面是生成的汇编代码

对于64位

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>
主函数的汇编程序代码转储: 0x000000000040105e:推送%rbp 0x000000000040105f:mov%rsp,%rbp 0x0000000000401062:子$0x10,%rsp 0x00000000004010066:movq$0x493564,-0x10(%rbp); 是由两个指针组成的数组。在32位机器上,指针(地址,但不一定)为32位宽,而在64位机器上,指针(和从不使用地址)为64位宽

这意味着,当前堆栈帧中堆栈上的区域必须为
2*指针\u宽度
,这使得32位机器的
8
,64位机器的
16

在下面的代码中,您可以看到

movl   $0x80027b8, -0x8(%ebp)
movl   $0x0, -0x4(%ebp)
。。。将32位DWORD移动到指针(一个字符串地址和一个
NULL

另一方面,64位代码需要两个DWORD(8字节)来存储地址

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

64位系统从rbp声明16位(我想学习的位、字节或字)偏移量,而32位系统从ebp声明8位偏移量-我相信它是以字节为单位的,而不是以位.字节为单位的。偏移量是不同的,因为在64位模式下,一个地址需要8个字节而不是4个字节。你所说的“指针(而不是地址)是64位宽”是什么意思?在
LP64
模式下,指针和地址总是64位宽,所以你的回答让我困惑。@EmployeedRussian抱歉,我的意思是另一种方式。地址可以是64位宽,但仅当它们是虚拟的时。据我所知,物理地址目前不超过52位。当然,在本例中,我们讨论的是虚拟地址,因此该语句不适用。
movl$0x0,-0xC(%ebp)
应该是
movl$0x0,-0x4(%ebp)
,因为0xfffffc是十进制-4。这是有意义的,因为在内存中arg应该位于arg++之前(arg[0]位于arg[1]之前)。
movl   $0x80027b8, -0x8(%ebp)
movl   $0x0, -0x4(%ebp)
movq   $0x0, -0x8(%rbp)
movq   $0x493564, -0x10(%rbp)