我正在研究Kip Irvine的“x86处理器的汇编语言,第六版” ,非常喜欢它。
我刚刚在以下段落中了解了NOP助记符:
"It [NOP] is sometimes used by compilers and assemblers to align code to
even-address boundaries."
给出的示例是:
00000000 66 8B C3 mov ax, bx
00000003 90 nop
00000004 8B D1 mov edx, ecx
该书随后指出:
"x86 processors are designed to load code and data more quickly from even
doubleword addresses."
我的问题是:是这样的原因是因为对于本书所指的x86处理器(32位),CPU的字长为32位,因此它可以将带有NOP的指令提取为一个指令并进行处理。走 ?如果是这种情况,我假设一个字大小为四字的64位处理器将使用假设的5个字节的代码加上nop?
最后,在编写代码之后,我是否应该仔细检查并与NOP正确对齐以对其进行优化,还是应该由编译器(在我的情况下为MASM)为我执行此操作,如文本所示?
谢谢,
史考特
最佳答案
在字(对于8086)或DWORD(80386及更高版本)边界上执行的代码执行速度更快,因为处理器会提取整个(D)字。因此,如果您的指令未对齐,则加载时会出现停顿。
但是,您无法对每条指令进行双字对齐。好吧,我想您可以,但是那样您将浪费空间,处理器将不得不执行NOP指令,这将失去对齐指令的任何性能优势。
在实践中,仅在指令是分支指令的目标时,在dword(或任何其他)边界上对齐代码才有帮助,并且编译器通常会对齐函数的第一条指令,但不会对齐也可以通过以下方式达到的分支目标:掉下去。例如:
MyFunction:
cmp ax, bx
jnz NotEqual
; ... some code here
NotEqual:
; ... more stuff here
生成此代码的编译器通常会对齐
MyFunction
,因为它是一个分支目标(已通过call
到达),但它不会对齐NotEqual
,因为这样做会插入NOP
指令,该指令在掉入时必须执行。这增加了代码大小,并降低了穿透速度。我建议如果您只是在学习汇编语言,则不要担心像这样的事情通常会给您带来微不足道的性能提升。只需编写代码以使一切正常。它们起作用后,您可以对其进行概要分析,如果在查看概要文件数据后认为有必要,可以调整功能。
汇编程序通常不会自动为您完成此操作。
关于assembly - 为什么代码应该与x86上的偶数地址边界对齐?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4909563/