【问题标题】:Call stack of x86 saving a single bytex86 的调用栈保存一个字节
【发布时间】:2011-10-13 11:51:50
【问题描述】:

我目前正在使用“Linux 中的汇编语言指南”学习 x86 汇编,在第 241 页上写到只有 16 位字或 32 位字被保存到堆栈中,但这是真的吗? 我的意思是在 C 中,一个 char 数组由单个字节组成,这些字节被保存到堆栈中,因为 C 由使用调用堆栈的函数组成,对吧?那我怎么了?

【问题讨论】:

标签: c assembly stack x86 callstack


【解决方案1】:

偶数字节用零填充并在被推送之前转换为 16 位或 32 位字。

将堆栈视为一堆特定尺寸(16 或 32)的盘子。有没有办法可以推动一半大小的盘子.. 没有?即使你想推一半,你也要把它垫成全尺寸的盘子,然后再推。

【讨论】:

  • 我想在另一篇文章中对此发表评论,但有人或作者删除了它,不管我的另一个问题是什么:所以基本上 C 会这样做来初始化 char 数组的第一个元素:movb 65 美元,(%esp)索引 0?在此之前它会做一些类似 sub sizeofarray, %esp ?
  • @rob:我已经取消删除它,因为它不再是错误的 :-) 基本上是的,但是请查看反汇编以了解您的实现究竟做了什么。数组的开头是否正好在esp 上取决于您还有哪些其他自动变量。
【解决方案2】:

push 指令确实如此,但这不是使用堆栈的唯一方法。 x86 也有 esp 寄存器来存储指向当前堆栈位置的指针。

函数参数在堆栈上,如果你检查一些反汇编,你会看到编译器是如何把它们放在那里的。在 x86 的通常调用约定中,char 参数每个占用 4 个字节。数组不能按值传递,所以如果可以的话,如何保存 char 数组的问题就不会出现。

自动变量也占用堆栈,但数组元素不会使用“推送”单独保存到堆栈中。通常,该函数会在开始时为其所有自动变量腾出空间 - 寻找涉及“esp”的“sub”指令。然后数组的开始在 esp 的一个已知偏移处,就像任何自动变量一样,编译器将使用这个偏移来生成对数组的访问。元素之间不需要填充,尽管数组末尾可能有一些填充以保持堆栈指针正确对齐。

【讨论】:

    猜你喜欢
    • 2015-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-10
    • 1970-01-01
    • 2020-09-16
    • 2013-12-31
    • 1970-01-01
    相关资源
    最近更新 更多