我感到困惑在FreeBSD 9.0/amd64上也是如此。 (我使用NASM的汇编),我所做的是:
$ cat foo.asm
global _start
_start:
mov rax, 4 ; write
mov rdi, 1 ; stdout
mov rsi, rsp ; address
mov rdx, 16 ; 16bytes
syscall
mov rax, 1 ; exit
syscall
$ nasm -f elf64 foo.asm && ld -o foo foo.o
$ ./foo | hd
00000000 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 |................|
00000010
$ ./foo 2 | hd
00000000 02 00 00 00 00 00 00 00 b8 dc ff ff ff 7f 00 00 |................|
00000010
$ ./foo 2 3 | hd
00000000 00 00 00 00 00 00 00 00 03 00 00 00 00 00 00 00 |................|
00000010
$ ./foo 2 3 4 | hd
00000000 00 00 00 00 00 00 00 00 04 00 00 00 00 00 00 00 |................|
00000010
$ ./foo 2 3 4 5 | hd
00000000 05 00 00 00 00 00 00 00 b0 dc ff ff ff 7f 00 00 |................|
00000010
我预期的argc在RSP,但事实并非如此。
我猜想内核(图像激活器)设置寄存器。我搜索了源代码树,在/usr/src/sys/amd64/amd64/machdep.c(exec_setregs)中找到了以下代码。
regs->tf_rsp = ((stack - 8) & ~0xFul) + 8;
regs->tf_rdi = stack; /* argv */
这些行看起来是说rsp是对齐的,实际数据是rdi。我改变了我的代码,并获得了预期的结果。
$ cat foo.asm
global _start
_start:
push rdi
mov rax, 4 ; write
mov rdi, 1 ; stdout
pop rsi
mov rdx, 16 ; 16bytes
syscall
mov rax, 1 ; exit
syscall
$ nasm -f elf64 foo.asm && ld -o foo foo.o
$ ./foo | hd
00000000 01 00 00 00 00 00 00 00 b0 dc ff ff ff 7f 00 00 |................|
00000010
$ ./foo 2 | hd
00000000 02 00 00 00 00 00 00 00 a8 dc ff ff ff 7f 00 00 |................|
00000010
$ ./foo 2 3 | hd
00000000 03 00 00 00 00 00 00 00 a8 dc ff ff ff 7f 00 00 |................|
00000010
$ ./foo 2 3 4 | hd
00000000 04 00 00 00 00 00 00 00 a8 dc ff ff ff 7f 00 00 |................|
00000010
$ ./foo 2 3 4 5 | hd
00000000 05 00 00 00 00 00 00 00 a8 dc ff ff ff 7f 00 00 |................|
00000010
你可以试试偏下?
尝试在调试器中运行它以查看堆栈布局是否符合您的期望。 – user786653
谢谢,我已经有一段时间了,通常8(%esp)有argc,但有时候不会,我想我会继续努力吧! :) – timmmay