3

在 DEC PDP-8 小型机的每个程序开始时,我没有失败地发出的第一条指令是CLA CLL清除累加器和链接(溢出)位。

8086 系列处理器中似乎不存在这种简单的指令,我在各种技术网站上看到了很多关于最快方法的讨论,比如与自身进行异或运算。

这是否已经由处理器逻辑处理?那么在程序启动前就保证为0?

4

4 回答 4

2

对于 8086,清除 AX 寄存器(不是 EAX)的最快和更短的方法是发出一些执行操作的 ALU 指令。那是:

xor ax,ax  ; opcode: 29 C0

或者

sub ax,ax  ; opcode: 31 C0

最短,因为常规mov ax,0需要 3 个字节:B8 00 00,多一个字节。最快,因为xor使用sub3 个时钟周期。mov使用 4 个周期。

另一方面,xorandsub会改变标志,而 mov 不会。有时您不介意在需要清除寄存器时更改标志,有时您不想更改标志。关于代码清除,xor/sub“技巧”广为人知,编译器确实使用它来快速清除寄存器,所以任何汇编程序员都会意识到你想要做什么。

于 2013-11-25T21:41:52.953 回答
1

程序启动时处理器寄存器中的内容无关紧要(x86堆栈指针除外)。如果您不喜欢寄存器中的垃圾,只需将它们设置为您喜欢的值。

这可能会在代码开头花费您全部 10 条指令。实际上,您不需要初始化您没有立即使用的寄存器,因此它只有 1 或 2 条指令。更重要的是,大多数汇编程序都比这大得多,所以没人关心。

如果您坚持,您可以通过将寄存器归零(xor reg,reg/sub reg,reg/mov reg,0)来初始化您的寄存器。

值得知道的是,处理器可以利用某些指令。在现代 Intel 芯片(不一定是 x86)上,“xor reg,reg”打破了对“reg”的管道依赖,从而实现了更快的代码,因此您应该尽可能坚持使用此类指令。

于 2013-11-25T19:08:58.913 回答
0

如果我们首先使用同一寄存器的 16 位部分并且想要在我们的以下说明中将访问更改为 32 位,则还建议对 32 位寄存器使用“xor reg,reg”。
例子:

LOCATION DW 3

xor eax, eax
mov ax, [LOCATION] ; first a 16 bit access to the lower part of EAX
shl eax, 2         ; following by a 32 bit access

xor 指令可以更快地执行我们的代码。我认为 movzx 指令的执行速度会较慢。

短剑

于 2014-01-07T11:50:37.667 回答
-1

xormov做不同的事情。xor将设置条件位并且mov不会。如果您的目标是将寄存器设置为特定值,mov则将清楚地传达给软件的读者。

优化汇编器有时可以安全地转换mov reg, 0xor reg, regor sub reg, reg

sub reg, reg并且xor reg, reg不一定会一直以同样快的速度执行。减法需要携带和异或不需要。携带通常以极其有效的方式实施,并且难以衡量所花费的额外时间,因此出于实际目的,人们倾向于将它们称为具有同样快速的执行。

于 2013-11-25T18:27:23.313 回答