【发布时间】:2010-12-16 22:31:42
【问题描述】:
我是一名业余时间学习汇编语言的大学生。我注意到虽然有 add 和 mul 之类的指令,但算术运算符经常在指令中使用。例如:
mov eax,[ebx+ecx]
是否等价于以下?
add ebx,ecx
mov eax,[ebx]
(忽略ebx内容的变化)
【问题讨论】:
我是一名业余时间学习汇编语言的大学生。我注意到虽然有 add 和 mul 之类的指令,但算术运算符经常在指令中使用。例如:
mov eax,[ebx+ecx]
是否等价于以下?
add ebx,ecx
mov eax,[ebx]
(忽略ebx内容的变化)
【问题讨论】:
几乎... 此索引地址方法([ebx+ecx] 或任何其他方法)通常用于寻址某些数组或记录中的元素。在您的情况下, ebx 可以是指向字节数组的指针,而 ecx 是索引。使用索引寻址可能很危险,因为算术运算后没有影响标志,因此我们无法检查数组范围溢出。通常调试模式下的高级编译器使用 clasic 较慢的方法,以便我们能够检测数组范围溢出。当我们将编译器切换到发布模式时(并且我们确信没有更多可能的错误),更快的索引寻址方法正在使用中。
【讨论】:
不,它不等价。如果这是真实代码,那么括号内的内容就是addressing mode 的示例。寻址模式控制如何计算操作的有效地址,但它通常没有持久效果。您的第二个代码 sn-p 实际上会添加到 ebx 寄存器,更改其内容以适应任何后续指令。
更新:我刚刚看到你关于忽略更改的最后一句话......如果你想忽略它,那么是的,我相信这两个 sn-ps 是等价的。
【讨论】:
就从内存中读取某些内容而言,它们在功能上是相同的。已经提到的差异在严格用于寄存器偏移寻址 [ebx+ecx] 时不会修改标志,并且您修改 ebx 并破坏您的基地址。您还消耗两倍的指令,两倍的取指。 x86 是可变指令长度,这并不一定意味着指令的字节数增加一倍,但它确实意味着执行相同任务需要更多的时钟周期和更多的缓存空间。
希望您能在自己的时间继续学习汇编,我建议您也学习其他指令集(ARM、thumb、mips、msp430、avr 等)。您经常会看到这些权衡,有时您特别希望在不破坏寄存器和不修改标志的情况下进行添加。有时,您希望或需要寄存器偏移寻址以使代码更快或更清晰,而不是必须为每个循环上的每个引用消耗一个寄存器和一条额外的指令。知道许多处理器都有寄存器偏移寻址,如果您对性能感兴趣,例如通用和目标特定,您可以编写高级代码来利用这些东西。
【讨论】: