可变位移操作

3

我希望将一个寄存器的位向左移动n次,这个n次是用另一个寄存器指定的。例如,类似这样:

shl    eax, ebx

唯一的问题是第二操作数不能是寄存器,必须是立即数。我该如何将寄存器按一个在汇编期间不知道的值进行移位?


你是否在C/C++中编写内联汇编? - evanmcdonnal
不,否则我就会使用移位运算符了。 - 123
2
你应该阅读指令集参考。 - Jester
1个回答

17
在x86中,您可以在寄存器cl中指定移位计数。因此shl eax,cl是有效的。
mov   ecx, ebx
shl   eax, cl

请注意,您只能使用cl寄存器,而不能使用eax或任何其他寄存器。
此外,大于31的移位计数将执行模32操作。(不是模操作数大小,因此像shl ax, 20这样的窄移位可能会将所有位移出并使目标为零。64位移位将使用& 63屏蔽计数,因此shl rax,32(或在cl中加32)是可能的。有关更多信息,请参见英特尔手册中对shl的条目)。
BMI2指令集扩展支持任何寄存器中的计数位移,并且不更新EFLAGS,因此它们对于可变计数更加高效。
; if BMI2 is supported
shlx   edx, eax, ebx     ; edx = eax << (ebx&31)

它只能在一些Haswell+ CPU,Excavator / Ryzen CPU上使用,因此您无法在完全可移植的代码中使用它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接