【发布时间】:2015-01-08 02:38:15
【问题描述】:
我有一个打印文本和浮点数的函数。这是一个不使用main的版本
extern printf
extern _exit
section .data
hello: db 'Hello world! %f',10,0
pi: dq 3.14159
section .text
global _start
_start:
xor eax, eax
lea rdi, [rel hello]
movsd xmm0, [rel pi]
mov eax, 1
call printf
mov rax, 0
jmp _exit
我像这样组装和链接这个
nasm -felf64 hello.asm
ld hello.o -dynamic-linker /lib64/ld-linux-x86-64.so.2 -lc -melf_x86_64
这运行良好。但是,现在我想使用main 来执行此操作。
global main
extern printf
section .data
hello: db 'Hello world! %f',10,0
pi: dq 3.14159
section .text
main:
sub rsp, 8
xor eax, eax
lea rdi, [rel hello]
movsd xmm0, [rel pi]
mov eax, 1
call printf
mov rax, 0
add rsp, 8
ret
我像这样组装和链接
nasm -felf64 hello_main.asm
gcc hello_main.o
这也运行良好。但是,我必须在调用printf 之前从堆栈指针中减去八个字节,然后在调用printf 之后将八个字节添加到堆栈指针中,否则会出现分段错误。
查看堆栈指针,我发现不使用 main 时它是 16 字节对齐的,但使用 main 它只有八字节对齐。必须减去和添加八个字节的事实表明它始终是 8 字节对齐的,而不是 16 字节对齐的(除非我误解了某些东西)。为什么是这样?我认为使用 x86_64 代码我们可以假设堆栈是 16 字节对齐的(至少对于我认为包括 main 的标准库函数调用)。
【问题讨论】:
标签: linux gcc assembly nasm x86-64