我在理解rlwinm
PPC汇编指令时遇到了一些麻烦(旋转左字然后立即使用遮罩)。
我试图扭转函数的这一部分
rlwinm r3, r3, 0, 28, 28
我已经知道r3
是什么了。在这种情况下,r3
是一个4字节的整数,但我不确定这条指令rlwinm
到底做了什么。
顺便说一句,这是在32位机器上。
答案 0 :(得分:6)
您的理解不是完全正确。根据此说明中的IBM link,您看到的表单是:
rlwinm <target=r3>, <source=r3>, <shift=0>, <begin-mask=28>, <end-mask=28>
因此不涉及实际转变。用于AND
操作的实际掩码是从begin
和end
掩码位置构建的,它不作为显式参数给出< SUP>(a)中
在这种情况下,由于两个位置都是28,因此根据链接页面(略微改述),掩码只是一个位:
如果 begin-mask 值小于 end-mask 值加1,则设置起点和终点之间(包括起点和终点)的掩码位到了。所有其他位都设置为零。
因此,您所看到的指示并不比单个AND
操作复杂。
(a) 是一个允许你指定实际掩码的表单(假设它由连续的一位组成),但它是< em>四个 -argument版本,实际上只是语法糖,汇编程序可以变成五参数。
答案 1 :(得分:2)
@ paxdiablo的答案是正确的,但要添加一些更多的背景信息:
各种r*
指令(rlwinm,rlwimi等)用于提取在编译时已知大小的位字段,例如C struct bitfields,或者甚至只是将一个字拆分为字节(可能是一个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
。