0

我使用 GCC 编译了以下 C 代码并在 gdb 中反汇编为程序集。我正在使用带有 64 位 Intel i5 处理器的 Macbook pro。在“main()”中,“char* name[2]”有 2 个字符指针,应该让堆栈指针减少 2 个字(16 个字节)?但是,当我在 gdb 中反汇编时,它减少了 20 ......有人可以帮助我理解吗?C代码:

#include <stdio.h>
#include <unistd.h>
int main(void)
{   
    char* name[2];
    name[0] = "/bin/sh";
    name[1]= NULL;
    execve(name[0],name,NULL);
}

gdb反汇编代码:

GNU gdb 6.3.50-20050815 (Apple version gdb-1708) (Thu Nov  3 21:59:02 UTC 2011)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin"...Reading symbols for shared libraries .. done

(gdb) disassemble main
Dump of assembler code for function main:
0x0000000100000ee0 <main+0>:    push   %rbp
0x0000000100000ee1 <main+1>:    mov    %rsp,%rbp
0x0000000100000ee4 <main+4>:    sub    $0x20,%rsp
0x0000000100000ee8 <main+8>:    lea    -0x18(%rbp),%rax
0x0000000100000eec <main+12>:   lea    0x61(%rip),%rcx        # 0x100000f54
0x0000000100000ef3 <main+19>:   mov    %rcx,-0x18(%rbp)
0x0000000100000ef7 <main+23>:   movq   $0x0,-0x10(%rbp)
0x0000000100000eff <main+31>:   mov    -0x18(%rbp),%rcx
0x0000000100000f03 <main+35>:   mov    $0x0,%rdx
0x0000000100000f0d <main+45>:   mov    %rcx,%rdi
0x0000000100000f10 <main+48>:   mov    %rax,%rsi
0x0000000100000f13 <main+51>:   callq  0x100000f22 <dyld_stub_execve>
0x0000000100000f18 <main+56>:   mov    -0x4(%rbp),%eax
0x0000000100000f1b <main+59>:   add    $0x20,%rsp
0x0000000100000f1f <main+63>:   pop    %rbp
0x0000000100000f20 <main+64>:   retq   
End of assembler dump.
4

3 回答 3

4

因此,在读取程序集时,名称 [0] 在堆栈上位于 -0x18,名称1位于 -0x10。此外,如前所述,-0x4 用于返回值。

剩下 12 个字节,因为 0x20 实际上是 32。范围 -32 到 -24 和范围 -8 到 -4。-8 到 -4 肯定是对齐的,我猜 -32 到 -24 也是如此(对于 16 字节对齐)。

编辑:请注意,实际上减去了 48 个字节。调用 main 的 callq 指令从 RSP 中减去 8 个字节,然后push %rbp再减去 8 个字节。

已验证的 16 字节对齐:x86-64 System V ABI第 3.2.2 节(直接链接到旧版本的 PDF

于 2012-11-04T21:24:51.160 回答
1

我猜想这种“奇怪的”堆栈帧格式与“惰性绑定”调用约定有关,这显然是在您调用的情况下使用的。即你实际上是在调用惰性绑定存根dyld_stub_execve,而不是它execve本身。调用后读取的结果代码-0x4(%rbp)可能是在绑定不成功的情况下返回的错误代码。

如果您静态链接库,我猜为调用准备的堆栈帧看起来会更传统。

PS我的回答可能是胡说八道,因为堆栈帧形成代码是在适当的编译过程中生成的,而使用静态或共享库的决定仅在链接时做出。

于 2012-11-04T21:16:14.893 回答
0

如果您在谈论 line <main+4>,它不是减去 20(以 10 为底)。它以 16 为基数减去 20,16^1 * 2 + 16^0 * 0即等于 32,或 2 个字的大小。

于 2012-11-04T21:17:05.120 回答