在ppc指令体系中,一次最多加载16位立即数。要加载32位立即数,必须分两次进行。很多资料上使用如下加载指令:
lis r0, 0x1122
addi r0, r0, 0x3344
这样做确实可以成功地把0x11223344加载到r0中。可是如果换成0x11118000呢?
lis r0, 0x1111
addi r0, r0, 0x8000
请注意, addi指令是r0 = r0 + EXTS(0x8000). EXTS(0x8000) = 0xffff8000。如此,加载到r0中的值就不是0x11118000,而是0x11108000。差之毫厘,谬以千里。
那gcc是如何实现加载32位立即数的指令的呢?
首先是加载0x11223344的指令, 这是对c代码反汇编得出的指令:
lis r0, 0x1122
ori r0, r0, 0x3344
gcc放弃了addi指令,转而使用ori指令。ori指令是r0 = r0 | (16'0 | 0x8000),加载到r0中的为0x11223344。
然后是加载0x11118000的指令,自然也是用ori指令:
lis r0, 0x1111
ori r0, r0, 0x8000
所以说,加载32位立即数时要小心,如果其第15位为1,用addi就会加载出错误的数值,还是用ori较为保险
其实,在ppc指令中,加载32位立即数并不是很常见,常见的是需要将一个数从一个32位