Assembly BSD堆栈清理
我正在学习汇编语言,对调用约定和堆栈清理有疑问 因为我使用的是OSX,所以我需要对系统调用使用BSD调用约定,如下所示Assembly BSD堆栈清理,assembly,stack,calling-convention,Assembly,Stack,Calling Convention,我正在学习汇编语言,对调用约定和堆栈清理有疑问 因为我使用的是OSX,所以我需要对系统调用使用BSD调用约定,如下所示 SECTION .text push StringLen ; Push string length push MyString ; Push the string push 0x1 ; Push the file descriptor (stdout) mov eax, 4 ; Push the system call (
SECTION .text
push StringLen ; Push string length
push MyString ; Push the string
push 0x1 ; Push the file descriptor (stdout)
mov eax, 4 ; Push the system call (sys_write)
int 0x80 ; Call kernel dispatcher
add esp, 0x10 ; Clean up stack 16 bytes for 4DWORDS
mov eax, 1
mov ebx, 0
int 0x80 ; System exit
我的问题是,addesp,0x10
是否被认为是清理堆栈的良好实践?我已经做过实验,在清理之后,这些值似乎仍然在堆栈上,但是当推送另一个值时会被覆盖,例如
add esp, 0x10 ; Clean up stack 16 bytes for 4DWORDS
push 0x1A ; New push overwrites the previous stack values
我相信这在一个小程序中不会造成很大的差异,但是在一个大程序中,如果它从未被覆盖,它不是浪费了空间吗
但是在一个大的系统中,如果它从未被覆盖,它不是浪费了空间吗
不,这不是浪费空间。堆栈空间的16个字节将一次又一次地被重用。是的,这种传递参数并清除它们的方法很好。但是,代码中存在一个问题:您只有三个推送,但减去16个字节。移动到
eax
不算作推送,因为它不会更改esp
这在这个小程序中可能无关紧要,但在任何大小合适的程序中都会崩溃。因此,修复0x10到0x0C添加一个推eax
或子esp,4
,以使其平衡并符合BSD调用约定的要求
另一种方法是预先保留堆栈空间,并使用mov
s来设置参数,而不是push
es
编辑:根据(额外推送)修复代码
如您所见,它避免了在函数体的大部分时间内更改ESP
,但它使代码更大、更详细。由于不能mov
内存对内存,因此必须使用临时寄存器来存储变量
出于某种原因,这种传递参数的方式是GCC的默认方式,会导致相当可观的代码膨胀。那么您认为这是清理堆栈的一种好方法吗?我只是想在早期坚持好的技术。@JamesParker:这可能是最好的方法。你有没有其他你认为更优越的选择?没有,一点也没有。我只是想和一些有经验的程序员核实一下,而不是把一篇文章当作真理。谢谢你的帮助。很有趣。我在我的代码中推了EAX,但不小心把它复制错了,谢谢你指出了这一点。啊,我没有意识到BSD调用约定需要它。修正了代码。正如您所见,《FreeBSD指南》实际上也使用了推送功能,因此它完全符合犹太规范:)
SECTION .text
; we only need 12 bytes (3 args) but BSD ABI needs one extra stack slot
sub esp, 0x10
mov eax, StringLen
mov [esp-C], eax
mov eax, StringLen
mov [esp-8], eax
mov dword [esp-4], 0x1 ; file descriptor (stdout)
mov eax, 4 ; system call number (sys_write)
int 0x80 ; make the syscall
mov dword [esp-4], 0 ; exit code
mov eax, 1 ; system call number (sys_exit)
int 0x80 ; System exit
; unreachable in this case but necessary for returning functions
add esp, 0x10 ; restore the stack at the end of the function