基本上,我阅读了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精灵的初始堆栈布局是什么?相当于http://asm.sourceforge.net/articles/startup.html会非常好。
更新2: 我遗漏了如何构建此代码。我是这样做的:
nasm -f elf64 -g <filename>
gcc <filename>.o -o <outputfile>
答案 0 :(得分:1)
初始堆栈布局在堆栈指针处包含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