32位PPC rlwinm指令

时间:2017-10-22 01:35:59

标签: c++ assembly reverse-engineering instruction-set powerpc

我在理解rlwinm PPC汇编指令时遇到了一些麻烦(旋转左字然后立即使用遮罩)。

我试图扭转函数的这一部分

rlwinm r3, r3, 0, 28, 28

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

顺便说一句,这是在32位机器上。

2 个答案:

答案 0 :(得分:6)

您的理解不是完全正确。根据此说明中的IBM link,您看到的表单是:

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

因此不涉及实际转变。用于AND操作的实际掩码是从beginend掩码位置构建的,它不作为显式参数给出< 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