2011-07-26 35 views
2

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

+1

可能的重复[为什么无法将字节推入Pentium IA-32上的堆栈?](http://stackoverflow.com/questions/2586591/why-is-it-not-possible-to -push-a-byte-on-a-stack-on-pentium-ia-32)分解你编译的内容,然后让我们讨论一下。 –

回答

5

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

将堆栈看作特定尺寸(16或32)的一堆板。有没有办法推出一半尺寸的板子?不是吗?即使你想推大一半的尺寸,你也可以用它来制作全尺寸的印版,然后再推。

+0

我想在其他帖子上发表评论,但有人或作者删除了它,无论在这里,我的另一个问题:所以基本上C会做这样的初始化char数组的第一个元素:movb $ 65,(%esp)for索引0?并在此之前,它会做一些像sub sizeofarray,%esp? – rob

+0

@rob:我现在已经没有错误了,现在它再也没有错了:-)基本上可以,但是要仔细查看反汇编以确切了解您的实现。数组的开始是否正好在'esp'上,取决于你拥有的其他自动变量。 –

2

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

函数参数放在堆栈上,如果你检查一些反汇编,你会看到编译器如何获取它们。在x86的通常调用约定中,参数char每个占用4个字节。数组无法通过值传递,所以如果可以的话,char数组将不会被保存。

自动变量也占用堆栈,但数组元素没有单独使用“push”保存到堆栈中。一般来说,函数会在开始时为所有自动变量创建空间 - 查找涉及“esp”的“子”指令。然后,数组的起始位置与esp的偏移量相同,就像任何自动变量一样,编译器将使用此偏移量来生成对数组的访问。在元素之间不需要填充,虽然在数组结束之后可能会有一些填充以保持堆栈指针正确对齐。