【发布时间】:2020-12-05 23:21:39
【问题描述】:
我尝试遵循https://cs.lmu.edu/~ray/notes/nasmtutorial/ 提供的一个非常简单的示例。 我故意在下面的行注释以确保堆栈未按照 x64 调用约定的要求与 16 字节边界对齐。但仍然程序继续工作。请有人回答为什么不遵守调用约定,我期待某种分段错误。
; sub rsp, 8 ; must align stack before call
为了运行这个程序:(Ubuntu 20.04 lts,gcc 9.3.0)
nasm -felf64 echo.asm && gcc echo.o && ./a.out 123ABC
; -----------------------------------------------------------------------------
; A 64-bit program that displays its command line arguments, one per line.
;
; On entry, rdi will contain argc and rsi will contain argv.
; -----------------------------------------------------------------------------
global main
extern puts
section .text
main:
push rdi ; save registers that puts uses
push rsi
; sub rsp, 8 ; must align stack before call
mov rdi, [rsi] ; the argument string to display
call puts WRT ..plt ; print it
; add rsp, 8 ; restore %rsp to pre-aligned value
pop rsi ; restore registers puts used
pop rdi
add rsi, 8 ; point to next argument
dec rdi ; count down
jnz main ; if not done counting keep going
ret
【问题讨论】:
-
如果您调用的函数(如 C 库(puts 等))是使用不需要对齐的指令(如某些 SSE/AVX 指令)编译/组装的,那么它们可能会按预期工作。如果您开始使用浮点运算(例如使用
printf的浮点),您通常会看到更多对齐问题。您可能会发现在 MacOS 上它失败了,因为他们似乎在他们的 C 库中使用了相当多的对齐指令,即使对于整数类数据也是如此。如果您不对齐堆栈,它可能会或可能不会工作。 -
您的问题类似于问:“我开车闯红灯,然后安全地开到了对面。我以为有人会撞到我。为什么要遵守交通规则不被尊重?”
标签: assembly x86-64 nasm glibc ubuntu-20.04