虽然我知道最好使用编译器内在函数,就此而言printf_chk
,以及将数据放入.rodata
部分,我正在寻求深入理解汇编语言我对紧凑的代码感兴趣。有一些关于printf
我不明白的事情。我知道在哪里放置参数,我知道如何使用%al
进行varargs,但它似乎需要额外的堆栈空间,我无法解释。
这个简短的程序
.text
.globl main
main:
movsd value(%rip), %xmm0 # value to print
movl $format, %edi # format string
movl $1, %eax # one floating-point arg
call printf
movl $0, %eax # return 0 from main
ret
.align 8
value: .double 74.321
format: .asciz "%g\n"
给出了段错误。
但是,当我向框架添加额外的堆栈空间时,它可以正常工作:
.text
.globl main
main:
subq $8, %rsp # ADD SOME STACK SPACE TO FRAME (WHY?)
movsd value(%rip), %xmm0 # value to print
movl $format, %edi # format string
movl $1, %eax # one floating-point arg
call printf
movl $0, %eax # return 0 from main
addq $8, %rsp # REMOVE ADDED STACK SPACE
ret
.align 8
value: .double 74.321
format: .asciz "%g\n"
这可能是对齐问题吗? (当value
和format
部分位于.rodata
部分时,我遇到同样的问题。)
答案 0 :(得分:4)
根据www.x86-64.org/documentation/abi.pdf以及Microsoft的http://msdn.microsoft.com/en-us/library/ms235286(v=vs.80).aspx
,堆栈必须是16字节对齐的。