基本上,我通读了 http://www.nasm.us/links/unix64abi 的部分内容在第 29 页,它显示了 C 程序的初始进程堆栈。
我的问题是:我正在尝试与 x86-64 nasm 中的 glibc 交互,根据上面显示的内容,argc 应该位于 rsp。所以下面的代码应该打印 argc:
[SECTION .data]
PrintStr: db "You just entered %d arguments.", 10, 0
[SECTION .bss]
[SECTION .text]
extern printf
global main
main:
mov rax, 0 ; Required for functions taking in variable no. of args
mov rdi, PrintStr
mov rsi, [rsp]
call printf
ret
但事实并非如此。如果我的代码有任何错误,有人可以启发我,或者告诉我实际的堆栈结构是什么吗?
谢谢!
更新:我只是随机尝试了一些偏移量并将“mov rsi, [rsp]”更改为“mov rsi, [rsp+28]”就成功了。
但这意味着显示的堆栈结构是错误的。有谁知道 x86-64 elf 的初始堆栈布局是什么?相当于 http://asm.sourceforge.net/articles/startup.html会非常好。
更新 2: 我省略了如何构建此代码。我这样做:
nasm -f elf64 -g <filename>
gcc <filename>.o -o <outputfile>
最佳答案
初始堆栈布局在堆栈指针处包含argc
,然后是数组 char *argv[]
,而不是指向它的指针就像 main
收到的那样。因此,要调用 main,您需要执行如下操作:
pop %rdi
mov %rsp,%rsi
call main
实际上通常有一个调用main
的包装函数,而不是直接在启动代码中调用。
如果你只想打印argv[0]
,你可以这样做:
pop %rdi
pop %rdi
call puts
xor %edi,%edi
jmp exit
关于c - 调用 glibc 时的 x86-64 ELF 初始堆栈布局,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5842001/