2012-08-22 182 views
2

任何人都可以向我解釋以下內容嗎?ARM彙編十六進制乘法運算

以下是乘以R1倍恆0x0110 003F而不使用乘法指令的最小長度ARM指令序列

ADD r2, r1, r1, LSL #4  //r2 = 0x11 * r1 
RSB r3, r1, r1, LSL #6  //r3 = 0x3F * r1 
ADD r3, r3, r2, LSL #20  //r3 = 0x0110 003F * r1 

我不知道爲什麼0x110X3F用來獲取0x0110 003F

任何人都可以熟悉ARM架構或者十六進制,請爲我解釋這個過程嗎?爲什麼使用RSB?

回答

5

數學無關與ARM ...

ADD r2,r1,r1, LSL #4 r2 = r1 + (r1 << 4); 
RSB r3,r1,r1, LSL #6 r3 = (r1 << 6) - r1; 
ADD r3,r3,r2, LSL #20 r3 = r3 + (r2 << 20); 

還記得小學乘法?

123 
x 12 
===== 
    246 
+123 
===== 
1476 

現在關於在二進制乘法的很酷的事情是,你要麼通過1或0乘人數爲每列(2的冪)。在上面的十進制數字中,基數(10)到數字0的數字中有一個2。在二進制(基2),我們不會有這個。對於十進制數列(基數爲1),就像我們將在二進制中看到的那樣,取頂部數字並將其乘以基數到1(向左移動一個位置)並將其加到/累加到結果中。

所以,如果我想在基地2(二進制)至乘以0b1011的東西,我有位3,1和0設置等等,

result = (x<<3) + (x<<1) + (x<<0); 

通過0x0110003F倍增,我們可以做一個附加對於8位中的每一位

result = (r1<<24)+(r1<<20)+(r1<<5)... 

但我們可以使用更多的基本數學。

rx * 0x3F 
0x3F = 0x40 -1 
rx * 0x3F = rx * (0x40 - 1) 
distribute 
rx * 0x3F = (rx * 0x40) - (rx * 1) 
rx * 0x3F = (rx * 0x40) - rx 
we know from the comments above that 
rx * 0x40 = rx << 6 
rx * 0x3F = (rx << 6) - rx 

現在

ADD r2,r1,r1,lsl 4 r2 = r1 + (r1 << 4) 

r2 = r1 + (r1 << 4) 
r2 = r1 + (r1 * 0x10) 
r2 = (r1 * 1) + (r1 * 0x10) 
r2 = r1 * (1 + 0x10) 
r2 = r1 * 0x11 

所以

r3 = r1 * 0x3F 
r2 = r1 * 0x11 

的最後一步是

result = r3 + (r2<<20) 
result = (r1 * 0x3F) + ((r1*0x11)<<20) 
result = (r1 * 0x3F) + ((r1*0x11)*0x100000) 
result = (r1 * 0x3F) + (r1*0x1100000) 
result = r1 * (0x3f + 0x1100000) 
result = r1 * 0x110003F 

爲什麼反向減法使用,是因爲執行

原因10
r3 = (r1 << 6) - r1 

與ARM指令可以做幾種方法:

mov r3,r1,lsl 6 r3 = (r1 << 6) 
sub r3,r3,r1  r3 = r3 - r1 

rsb r3,r1,r1,lsl 6 r3 = (r1 << 6) - r1 

RSB只是意味着反向減法,一個正常的減

sub ra,rb,rc means ra = rb - rc 

反向減法意味着顛倒操作數的順序

rsb ra,rb,rc means ra = rc - rb 

要對三個寄存器格式的操作數在這種情況下進行操作數轉換,它必須是最後一個操作數,所以如果您希望減去的左操作數移位,則使用rsb。

sub ra,rb,rc,lsl x means ra = rb - (rc << x) 
rsb ra,rb,rc,lsl x means ra = (rc << x) - rb 

我們希望通過rsb表單來保存指令。

0

以下是僞代碼的行(和小數):

r2 = r1 + (r1 <<4) == r1 * 16 + r1 == r1 * 17 
r3 = r1 << 6 - r1 = r1 * 64 - r1 = r1 * 63 
r3 = r3 + r2 << 20 = r3 + r2 * 1048576 

代線1和2到3:

r3 = (r1 * 63) + 1048576 * (17 * r1) = r1 * (63 + 17825792) = r1 * 17825855 

...而17825855十六進制是110003F

要回答爲什麼使用這些數字的問題,這將涉及到Peasant Multiplication和分解到轉換和增加。的110003F你的恆定值,實際上是這樣的:

(2 + 1)* 2 + 2 - 1

0

如果你熟悉C,這裏有一個線,由-line翻譯(使用變量而不是寄存器):

r2 = r1 + (r1 << 4); 
r3 = (r1 << 6) - r1; 
r3 = r3 + (r2 << 20); 

回想一下,r1 << 4相同r1 * 16,所以第一行說r2 = r1 + r1*16,或r2 = r1*17

同樣,r1 << 6r1 * 64,所以第二行說r3 = r1 * 64 - r1r3 = r1*63

遵循相同的模式,最後一行表示r3 = r3 + r2 * 1048576,它代替前面幾行的值,爲r3 = r1*63 + r1*17*1048576。這簡化爲r3 = 17825855 * r1r3 = 0x0110003f * r1