我在DEC PDP-8小型机的每个程序开始时发出的第一条指令是CLA CLL
来清除累加器和链接(溢出)位。
这个简单的指令似乎并不存在于8086系列处理器中,而且我已经在最快捷的方式上看到了很多关于各种技术网站的讨论,比如对它自己进行异或。
这是否已由处理器逻辑处理? 所以在程序开始之前保证为0?
答案 0 :(得分:1)
对于8086,清除AX寄存器(不是EAX)的最快和最短的方法是发出一些执行操作的ALU指令。那就是:
xor ax,ax ; opcode: 29 C0
或者
sub ax,ax ; opcode: 31 C0
最短,因为常规mov ax,0
需要3个字节:B8 00 00
,多一个字节。
最快,因为xor
和sub
使用3个时钟周期。 mov
使用4个周期。
另一方面,xor
和sub
将改变标志,而mov则不会。有时你不介意在需要清除寄存器时更改标志,有时你不会想要改变标志。关于代码清晰度,xor / sub“技巧”是众所周知的,并且编译器确实使用它来快速注册清除,因此任何汇编程序员都会意识到你想要做的事情。
答案 1 :(得分:0)
xor
和mov
执行不同的操作。 xor
将设置条件位,而mov
则不会。
如果您的目标是将注册表设置为特定值,mov
会清楚地将该注册表传达给您的软件读者。
优化汇编程序有时可以安全地将mov reg, 0
转换为xor reg, reg
或sub reg, reg
。
sub reg, reg
和xor reg, reg
并不一定会在所有时间内同样快速地执行。减法需要携带和排他或不。承载通常以极其有效的方式实施,并且所花费的额外时间难以测量,因此出于实际目的,人们倾向于将它们称为具有同样快速执行。
答案 2 :(得分:0)
程序启动时处理器寄存器中的内容是无关紧要的(x86堆栈指针除外)。如果您不喜欢寄存器中的垃圾,只需将它们设置为您喜欢的值即可。
在您的代码开头,这可能会花费您10条指令。在实践中,您不需要初始化您没有立即使用的寄存器,因此它只有1或2条指令。更重要的是,大多数装配程序比这大得多,所以没有人关心。
如果您坚持,可以通过将寄存器归零(xor reg,reg / sub reg,reg / mov reg,0)来初始化寄存器。
值得知道处理器可以利用某些指令。在现代英特尔芯片(不一定是x86)上,“xor reg,reg”打破了对“reg”的管道依赖性,实现了更快的代码,所以你应该坚持使用这些指令。
答案 3 :(得分: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-instruction可以更快地执行代码。我认为movzx指令的执行速度会慢一些。
德克