x86 mov / add说明&内存寻址

时间:2015-04-19 08:18:13

标签: memory assembly x86 att

我正在学习类中的x86程序集,我很遗憾你如何区分寄存器操作数和内存引用的作用。我有几个想要澄清的混乱。

以下代码是我的教科书所说的分别是推送和弹出的漫长道路:

subl $4, %esp
movl %ebp, (%esp)

movl (%esp), %eax
addl $4, %esp

那么在subl指令中,我们是否总能指望%esp保存地址值?

两个movl函数之间有什么区别?可以将第一个写成

movl (%ebp), %esp

?对于第二个movl,是移动%esp的地址还是移动%esp指向的值?

作为后续行动,为什么我们不能让源和目标成为这样的内存引用?

movw (%eax), 4(%esp)

最后,对于以下代码:

movb (%esp, %edx, 4), %dh

如果源超过1个字节(%dh的大小),那么会发生什么?它只是截断了这个值吗?

对不起,这是一个很多问题,但任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

  

以下代码是我的教科书所说的推进的漫长道路   并分别弹出:

subl $4, %esp
movl %ebp, (%esp)

movl (%esp), %eax
addl $4, %esp
     

所以在subl指令中,我们是否总能指望%esp持有   地址值?

是。 ESP寄存器保存推入堆栈的最后一个值的内存地址。

  

两个movl函数之间有什么区别?可以   第一个写成

movl (%ebp), %esp
     

?而对于第二个movl,是否会移动%esp或者地址   它移动%esp?

指向的值

MOV语法中的AT&T指令需要两个操作数:source和destination。 MOV将数据(在本例中为32位,由L后缀表示)从左侧写入的第一个操作数复制到第二个操作数(右侧写入)。如果其中一个括在括号中,则表示操作数是内存操作数,括号中的值是其内存地址,而不是实际值)

因此,movl %ebp,(%esp)表示:将寄存器EBP的值复制到内存中,位于寄存器ESP的值指向的地址。

您对movl (%ebp),%esp的意思是:将从EBP的值指向的内存地址开始的32位数据复制到ESP寄存器中。

所以你正在改变运动的方向。

  

作为后续行动,为什么我们不能拥有源和目的地   内存参考如此?

movw (%eax), 4(%esp)

简短回答:因为英特尔使用的编码不允许这样做。答案很长:英特尔设计ISA的方式,可用资源来计算好旧8086中的两个有效地址等等。

  

最后,对于以下代码:

movb (%esp, %edx, 4), %dh
     

如果源超过1个字节(%dh的大小),那么什么   发生?它只是截断了值吗?

源与目标的大小相同。这是由B后缀和目标是8位寄存器的事实强加的。括号中的值则是单个存储器字节的地址。顺便说一下,这个地址是ESP+EDX*4

答案 1 :(得分:1)

  

那么在subl指令中,我们是否总能指望%esp保存地址值?

根据定义是,因为下一条指令将其用作地址。无论垃圾是什么,现在都有一个地址。如果有一些像0xDEADBEEF这样的废话......那么现在这是一个地址。它可能是也可能不是有效地址(希望有效,无效堆栈有点不好),但这是另一回事。

  

两个movl函数之间有什么区别?

" push"中使用的那个写入内存,用于" pop"读取。右侧的括号表示它是一个写入,在左侧是它的读取。所以你可以切换它们吗?显然不是,它会做一些不同的事情。 movl (%ebp), %esp将从内存中读取内容,然后更改堆栈的位置。

  

作为后续行动,我们为什么不能将源和目标作为内存引用呢?

因为你不能,所以没有这样的指示。它不适合正常的operand encoding。我想这样的指示可能已经存在,但它没有,所以你不能使用它。

  

movb (%esp, %edx, 4), %dh如果源超过1个字节(%dh的大小),那么会发生什么?

根据定义,该指令不会读取1个字节。