gpt4 book ai didi

assembly - i386汇编问题: why do I need to meddle with the stack pointer?

转载 作者:行者123 更新时间:2023-12-03 05:01:26 25 4
gpt4 key购买 nike

我认为在暑假期间学习 x86 汇编会有趣。因此,我从一个非常简单的 hello world 程序开始,借用了 gcc -S 可以给我的免费示例。我最终得到了这个:

HELLO:
.ascii "Hello, world!\12\0"
.text

.globl _main
_main:
pushl %ebp # 1. puts the base stack address on the stack
movl %esp, %ebp # 2. puts the base stack address in the stack address register
subl $20, %esp # 3. ???
pushl $HELLO # 4. push HELLO's address on the stack
call _puts # 5. call puts
xorl %eax, %eax # 6. zero %eax, probably not necessary since we didn't do anything with it
leave # 7. clean up
ret # 8. return
# PROFIT!

它可以编译甚至可以工作!我想我理解其中的大部分

尽管如此,神奇的事情发生在第 3 步。如果我删除这一行,我的程序就会在调用 putsxor 之间因未对齐的堆栈错误而死掉。如果我将 $20 更改为另一个值,它也会崩溃。所以我得出的结论是这个值非常重要。

问题是,我不知道它的作用以及为什么需要它。

谁能给我解释一下吗? (我使用的是 Mac 操作系统,这有什么关系吗?)

最佳答案

在 x86 OSX 上,堆栈需要为函数调用进行 16 字节对齐,请参阅 ABI 文档 here 。所以,解释是

push stack pointer (#1)         -4strange increment (#3)         -20push argument (#4)              -4call pushes return address (#5) -4total                          -32

要进行检查,请将第 3 行从 $20 更改为 $4,这也有效。

此外,Ignacio Vazquez-Abrams 指出,#6 不是可选的。寄存器包含先前计算的剩余部分,因此必须明确将其清零。

我最近也学习了(仍在学习)汇编。为了避免您感到震惊,64 位调用约定有很大不同(参数在寄存器上传递)。找到this对于 64 位汇编非常有帮助。

关于assembly - i386汇编问题: why do I need to meddle with the stack pointer?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2982916/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com