例如,考虑如何在 C 中执行此操作,然后将其转换为 asm。
例如,使用 32 位变量进行一次左移,假设 ra 是高 32 位,rb 是低位
if(rb&0x80000000) { ra<<=1; ra|=1; rb<<=1 }
else { ra<<=1; rb<<=1; }
对于旋转,您可能会按照这些方式做一些事情
if(rb&0x80000000)
{
if(ra&0x80000000) { ra<<=1; ra|=1; rb<<=1: rb|=1; }
else { ra<<=1; ra|=1; rb<<=1; }
}
else
{
if(ra&0x80000000) { ra<<=1; rb<<=1: rb|=1; }
else { ra<<=1; rb<<=1; }
}
然后,您可以围绕其中一个循环并执行 N 次。
或者说左移 8 位
ra=(ra<<8)|(rb>>(32-8));
rb<<=8;
或者说左移 N 位
ra=(ra<<=n)|(rb>>(32-n));
rb<<=n;
或者 n 位向左旋转(这与 32-n 位向右旋转相同)(有些处理器只有向右旋转而左侧是虚拟的,反之亦然)。
temp=ra>>(32-n);
ra=(ra<<=n)|(rb>>(32-n));
rb=(rb<<<=n)|temp;
然后查看指令集,看看哪些是可用的并且与你正在做的相匹配。
简而言之,要移位位,您需要将位放在一侧并将其放入下一位。如果您将自己对齐在变量或寄存器之类的某个边界上,那么您从一侧获取位并将其转移到另一侧没有区别,它可能需要更多代码,因为指令集或编程语言不直接支持它并不意味着您不能做。就像您可以在没有乘法指令的情况下在 8 位处理器上执行 2048 位乘法一样,只需要比其他处理器更多的代码,但它非常可行。