您至少有以下问题:
-
堆栈布局用于初始入口点,而不是
main
。
-
你正在弹出
rbp
你只是推了一下,堆栈上没有任何东西。
-
你突然进入
rsp
(堆栈指针),稍后会咬到你:push/pop和call/ret指令使用
rsp
作为指针。
-
虽然
主要的
也得到
argc
作为一个参数,64位调用约定不会在堆栈上传递它。
-
你试图通过
argc
在里面
rdi
应该在什么时候
rsi
因为这是的第二个论点
printf
自从
int
是32位,您可以使用
esi
。
-
输出函数
试图解释
argc
作为字符串,因为您使用
%s
而不是
%d
在格式字符串中。
-
你不归零
%al
对于
输出函数
(这在实践中并不致命,因为它只需要是一个上界,所以在非古代版本的libc中,其中的任何值都应该有效。旧的GCC计算了一个间接跳跃,所以
AL values above 8 could crash
.)
可选:您的代码与位置无关,这在现代系统中是推荐的(有时也是必需的)。您可以将格式字符串放入
.rodata
因为它是只读的。
固定版本可能看起来像:
.globl main
main:
push %rbp # rbp not used, for alignment only
mov %edi, %esi # move argc to second parameter register
lea format_string(%rip), %rdi # the format string is the first parameter
xor %eax, %eax # 0 xmm registers used
call printf@plt
xor %eax, %eax # return 0 to behave nicely
pop %rbp
ret
.section .rodata
format_string: .string "Arguments: %d\n"