32 bit PPC rlwinm instruction

32 bit PPC rlwinm instruction

本文关键字:instruction rlwinm PPC bit      更新时间:2023-10-16

我在理解rlwinmPPC Assembly指令(先旋转左单词立即数,然后使用掩码进行AND)时遇到了一些问题。

我正在尝试反转的这部分功能

rlwinm r3, r3, 0, 28, 28

我已经知道r3是什么了。在这种情况下,r3是一个4字节的整数,但我不确定rlwinm对它到底做了什么。

顺便说一下,这是在一台32位的机器上。

您的理解并不完全正确。根据本说明书上的IBM链接,您看到的表格是:

rlwinm <target=r3>, <source=r3>, <shift=0>, <begin-mask=28>, <end-mask=28> 

因此,不涉及实际的转变。用于AND操作的实际掩码是由beginend掩码位置构造的,它不是作为显式参数(a)给出的。

在这种情况下,由于两个位置都是28,因此掩码只是一个比特,如链接页面所示(略有转述):

如果开始掩码值小于结束掩码

因此,您看到的指令并不比单个AND操作更复杂。


(a)是一种允许您指定实际掩码的形式(假设它由连续的一位组成),但它是四个参数的版本,实际上只是语法糖,汇编程序可以将其转换为五个参数的一个。

@paxdiablo的答案是正确的,但要添加更多上下文:

各种r*指令(rlwinm、rlwimi等)被设计用于提取在编译时大小已知的位字段,例如C结构位字段,或者甚至只是将字分割成字节(一个lw和四个rlwinm指令可能比几个单独的lbzu指令更快)。

lw r4, r3 ; load the word at the address pointed at by r3
rlwinm r5, r4, 8, 24, 31 ; first byte in r5
rlwinm r6, r4, 16, 24, 31 ; second byte in r6
rlwinm r7, r4, 24, 24, 31 ; third byte in r7
rlwinm r8, r4, 0, 24, 31 ; fourth byte in r8, identical to andi r8, r4, 255

在这种情况下,rlwinm指令也可以用作连续比特集的andi的特殊形式。由于PowerPC中的指令总是32位,所以取立即值的指令只有16位来保存这些值——因此,如果您想屏蔽一组跨越高/低半字边界的位,比如23到8,则需要使用多个操作。

lis r4, r4, 0x00ff ; first set bits 23 to 16 of the mask
ori r4, r4, 0xff00 ; then bits bits 15 to 8
and r3, r3, r4 ; then perform the actual masking 

然而,使用rlwinm指令,我们可以在单个指令中执行相同的操作:

rlwinm r3, r3, 0, 8, 23

在您的情况下,该值可能包含某些内容的标志,而此指令正在提取其中一个标志。下一条指令可能是r3上的条件分支。

ETA:Peter Cordes纠正了我的一些错误,对此我深表感谢,并补充说,在这种情况下可能没有必要使用rlwinm,而且可能只是编译器的一个特性导致生成此指令而不是andi