我一直试图了解ASM x64指令的0x40
REX操作码的用途。例如,在Kernel32.dll的这个函数序言中:
如您所见,他们使用push rbx
作为:
40 53 push rbx
但仅使用53h
操作码(不带前缀)也会产生相同的结果:
根据this site,REX前缀的布局如下:
所以40h
操作码似乎没有做任何事情。有人可以解释它的目的吗?
答案 0 :(得分:1)
04xh
字节(即040h
,041h
... 04fh
)确实是REX字节。正如您在问题中列出的那样,下半字节中的每个位都有含义。值040h
表示REX.W
,REX.R
,REX.X
和REX.B
都是0
。这意味着添加此字节不会对此指令执行任何操作,因为您不会覆盖任何默认REX位,并且它不是具有AH / BH / CH / DH的8位指令一个操作数。
此外,X
,R
和B
位都对应于某些操作数。如果指令不消耗这些操作数,则忽略相应的REX位。
答案 1 :(得分:0)
我称其为虚拟REX前缀,因为它在推送或弹出之前不执行任何操作。我想知道是否允许这样做,而您的经验表明确实如此。
之所以在这里,是因为Microsoft的人员显然生成了上述代码。我推测对于额外的寄存器而言,它是必需的,因此它们总是生成它,并且在不需要它时不会费心删除它。另一种可能性是指令的延长对调度和/或对齐有微妙的影响,并且可以使代码更快。当然,这需要特定处理器的详细知识。
我正在研究机器码的优化器。虚拟前缀很有用,因为它们使代码更加统一。需要考虑的情况较少。然后,最后一步就是可以删除多余的前缀。