2012-08-16 150 views
4
for (int i = 0; i < 10000; i++) 
    a[i] = b[i] + c[i] 

此高級語言的ARM彙編是什麼樣的?ARM彙編迴路

編輯: 我也假設A的基地址中R8,B的基 地址是在R 9和C的基地址是在R10 和A,B,C均爲INT陣列

非常感謝

我嘗試:

MOV R0, #0 ; Init r0 (i = 0) 

Loop: 

     a[i] = b[i] + c[i] //How to fix this? 

     ADD R0, R0, #1 ;Increment it 

     CMP R0, #1000 ;Check the limit 

     BLE Loop ;Loop if not finished 
+0

到目前爲止您嘗試過什麼? – 2012-08-16 02:13:55

+0

你可能想澄清你在這裏問的問題--ARM風格的Assembly和Android編程是兩個完全不同的東西; Android是像Java這樣的VM風格環境;你不能使用Assembly,因爲代碼是由運行時解釋的,而不是直接在處理器上運行。 – 2012-08-16 02:20:47

+0

關於你的編輯;你在什麼地方嘗試了ASM;你使用什麼軟件/設備? – 2012-08-16 02:23:51

回答

6

假設這個高級語言沒有任何與C衝突的東西,你可以使用arm C編譯器從你的代碼段中創建彙編代碼。例如,如果您在在test.c的下面,

void test() { 
     register int i asm("r0"); 
     register int *a asm("r8"); 
     register int *b asm("r9"); 
     register int *c asm("r10"); 

     for (i = 0; i < 10000; i++) { 
       a[i] = b[i] + c[i]; 
     } 
} 

可以運行

arm-linux-androideabi-gcc -O0 -S test.c 

創建test.s文件,其中將包含彙編代碼爲你的測試功能,以及一些額外的東西。你可以看到你的循環如何被編譯到下面的程序集中。

<snipped> 
.L3: 
     mov  r2, r8 
     mov  r3, r0 
     mov  r3, r3, asl #2 
     add  r3, r2, r3 
     mov  r1, r9 
     mov  r2, r0 
     mov  r2, r2, asl #2 
     add  r2, r1, r2 
     ldr  r1, [r2, #0] 
     mov  ip, sl 
     mov  r2, r0 
     mov  r2, r2, asl #2 
     add  r2, ip, r2 
     ldr  r2, [r2, #0] 
     add  r2, r1, r2 
     str  r2, [r3, #0] 
     mov  r3, r0 
     add  r3, r3, #1 
     mov  r0, r3 
.L2: 
     mov  r2, r0 
     ldr  r3, .L5 
     cmp  r2, r3 
     ble  .L3 
     sub  sp, fp, #12 
     ldmfd sp!, {r8, r9, sl, fp} 
     bx  lr 
<snipped> 

現在用這個方法的問題是信任編譯器生成你的研究的最佳代碼,這可能不是總是如此,但你會得到快速解答您的問題,如上述,而不是等待人:)

- 額外 -

GCC允許你把變量放到特定的寄存器,見related documentation

您可以獲取arm指令備忘單here

GCC的較新版本創建更好的代碼,如預期的那樣。上面的剪切版本是由4.4.3版生成的,我可以確認Linaro的4.7.1版本證明了我的說法。所以,如果你採用我的方法,可以使用最新的工具鏈。

4

http://www.peter-cockerell.net/aalp/html/ch-5.html

;Print characters 32..126 using a FOR loop-type construct 

;R0 holds the character 
MOV R0, #32 ;Init the character 
.loop 
SWI WriteC ;Print it 
ADD R0, R0, #1 ;Increment it 
CMP R0, #126 ;Check the limit 
BLE loop ;Loop if not finished 
; 
+1

這裏需要鹽的劑量;這個來源來自於1987年編寫的一本書。 theres很可能在2012年不適用於基於ARM的Android設備。 – 2012-08-16 02:22:35

1
for (int i = 0; i < 10000; i++) 
    a[i] = b[i] + c[i] 



mov r0,#0x2700 
orr r0,#0x0010 
top: 
ldr r1,[r9],#4 
ldr r2,[r10],#4 
add r1,r1,r2 
str r1,[r8],#4 
subs r0,#1 
bne top 
1

要建立在@alpera的答案上 - 您還可以展開循環,以便一次執行4個操作 - 儘管您是否獲得了性能優勢取決於內存訪問還是分支周圍的管道停頓是更大的影響

mov r11,#0x2700 
orr r11,#0x0010 
top: 
ldmia r9!, {r0-r3} 
ldmia r10!, {r4-r7} 
add r0,r0,r4 
add r1,r1,r5 
add r2,r2,r6 
add r3,r3,r7 
stmia r8!, {r0-r3} 
subs r11,#4 
bne top 

如果你有NEON單元得心應手,我們可以做到這一點這種方式 - 在這種情況下,將並行的加載,存儲並增加了 - 這實際上減少了問題,在執行循環的兩次迭代5個指令一旦。

默認情況下,AC編譯器不會生成這樣嚴密的代碼(或者爲NEON並行),因爲它必須假定用於讀寫的緩衝區(r8,r10和r11)可能會重疊 - 因此可能會寫入r8立即通過r9或r10在循環的下一次迭代中讀取。您可以使用restrict(在C++中爲__restrict)修飾符來告訴編譯器,情況並非如此。