我是PowerPC組裝的新手。我正在使用MPC8245(是的,舊學校)。這是一款603e家族處理器。PowerPC Assembly立即加載
我想知道如何創建一個立即的16位值爲'無符號'的立即加載指令。
實施例:LI r3,0xFC10
gcc的交叉編譯器,4.4.5,我使用不允許這種指令作爲值是不帶符號的常數。
是的,我可以使用減去2-s補碼,但是這使得閱讀和記錄代碼更加困難。裝載設備寄存器的位域時,指令中的確切位域更容易閱讀。
我是PowerPC組裝的新手。我正在使用MPC8245(是的,舊學校)。這是一款603e家族處理器。PowerPC Assembly立即加載
我想知道如何創建一個立即的16位值爲'無符號'的立即加載指令。
實施例:LI r3,0xFC10
gcc的交叉編譯器,4.4.5,我使用不允許這種指令作爲值是不帶符號的常數。
是的,我可以使用減去2-s補碼,但是這使得閱讀和記錄代碼更加困難。裝載設備寄存器的位域時,指令中的確切位域更容易閱讀。
li
是一個僞操作碼,它實際上翻譯爲addi
指令。
addi rD, rA, SIMM
增加了當rA
字段爲0,在這種情況下,它指定r0
字面0代替符號立即SIMM
到rA
,把結果放置在rD
,除了。 li rD, SIMM
確實是addi rD, 0, SIMM
。
這對從0
- 0x7fff
和0xffff8000
- 0xffffffff
加載值到寄存器,但不是其他值是好的。
立即按位操作操作碼(ori
等)將16位立即數字段解釋爲無符號值。但是,它們沒有「r0
」表示文字0
「addi
的行爲。
您將需要使用兩個指令的0xfc10
一個常數加載到寄存器:加載使用li
0寄存器(或lis
,因爲如果你是加載任意的32位常數的上半部分),然後OR與無符號16位值ori
。
這正是gcc
的情況下所做的:
$ cat test.c
unsigned int test(void)
{
return 0xfc10;
}
$ gcc -O2 -c test.c
$ objdump -d test.o
test.o: file format elf32-powerpc
Disassembly of section .text:
00000000 <test>:
0: 38 60 00 00 li r3,0
4: 60 63 fc 10 ori r3,r3,64528
8: 4e 80 00 20 blr
c: 60 00 00 00 nop
$
我不認爲的 GNU彙編器的自動生成兩個指令任何方式從單一的加載這樣的值PowerPC組裝時的源指令。但是你可以使用@h
和@l
後綴提取(簽名)高和低16位的常數,例如半:
lis r3, [email protected] /* => li r3, 0x1234 */
ori r3, r3, [email protected] /* => ori r3, r3, 0x5678 */
您可以使用它來編寫自己的任意常數加載宏.. 。
$ cat test2.s
.macro load_const rD, const
.if (\const >= -0x8000) && (\const <= 0x7fff)
li \rD, \const
.else
lis \rD, \[email protected]
ori \rD, \rD, \[email protected]
.endif
.endm
load_const r3, 0
load_const r4, 1
load_const r5, -1
load_const r6, 0x7fff
load_const r7, 0x8000
load_const r8, -32767
load_const r9, -32768
load_const r10, -32769
load_const r11, 0xfc10
$ as -mregnames -o test2.o test2.s
$ objdump -d test2.o
test2.o: file format elf32-powerpc
Disassembly of section .text:
00000000 <.text>:
0: 38 60 00 00 li r3,0
4: 38 80 00 01 li r4,1
8: 38 a0 ff ff li r5,-1
c: 38 c0 7f ff li r6,32767
10: 3c e0 00 00 lis r7,0
14: 60 e7 80 00 ori r7,r7,32768
18: 39 00 80 01 li r8,-32767
1c: 39 20 80 00 li r9,-32768
20: 3d 40 ff ff lis r10,-1
24: 61 4a 7f ff ori r10,r10,32767
28: 3d 60 00 00 lis r11,0
2c: 61 6b fc 10 ori r11,r11,64528
$
馬特 - 感謝您的徹底解答。我使用的構建環境具有'lwi'宏。如上所述,當使用帶有'li'的無符號值時,gcc報告的錯誤是「錯誤:操作數超出範圍(0x00008000不在0xffff8000和0x00007fff之間)」。 – KeithSmith
您還可以通過使用操作ori
加載未簽名的16位直接的,但可以肯定之前清除寄存器:
xor r3, r3, r3
ori r3, r3, 0xFC10
-1008與0xFC10具有相同的2的補碼錶示。也許你可以寫(0xfc10-0x10000)? –
或者手動將它擴展到0xFFFFFC10? –
@tc - 有趣。即使li指令只接受16位值,li r3,0xFFFFFC10也是一條合法指令。 – KeithSmith