新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設計應用 > arm匯編之冒泡排序

arm匯編之冒泡排序

作者: 時間:2016-11-11 來源:網(wǎng)絡 收藏
開始在ADS里面寫程序后,發(fā)現(xiàn)自己之前對于X86匯編的學習完全歸還給了我的老師門。最直接的便是要寫一個從小到大的冒泡排序。冒泡排序的思想我想就不用贅述了。以前c語言遍的應該很多了。算法不成問題,可是數(shù)據(jù)結構知道是數(shù)組,可是數(shù)組在arm匯編里面該在怎么定義了?

其實,還真感覺又要從零開始了。X86的匯編已經(jīng)完全歸還給了我敬愛的微機原理老師。

網(wǎng)上看到了一個廣為流傳的冒泡排序,既然寫不出來,那就先學習它的精髓,說不定還能為我所用了。




代碼詳細的看了看。具體翻譯如下(arm匯編指令不太熟悉,就當時溫習吧):

AREA Sort,CODE,READONLY :首先用AREA偽代碼加上CODE,表明下面引出的將是一個代碼段(于此相對的還有數(shù)據(jù)段DATA),ENTRY 和END成對出現(xiàn),說明他們之間的代碼是程序的主體

ENTRY:表示代碼的開始
Start MOV r4,#0 :將0賦值給r4
LDR r6,=src :在使用LDR時,當格式是LDR r0,=0x022248,則第二個參數(shù)表示地址,即0x022248,同樣的,當src變量代表一個 數(shù)組時,需要r0寄存器指向src則需要這樣賦值:LDR r0,=src 當格式是LDR r0,[r2],則第二個參數(shù)表示寄存器,我的理解是[]符號表示取內容,r2本身表示一個寄存器地址,取內容候將其存取r0這個寄存器中跳轉到 LDR R0,[R1]將存儲器地址為R1的字數(shù)據(jù)讀入寄存器R0 LDR R0,[R1,#8]將存儲器地址為R1+8的字數(shù)據(jù)讀入寄存器R0,并將新地址R1+8寫入R1,此句是將數(shù)據(jù)src的首地址賦值給R6

ADD r6,r6,#len:R6為數(shù)組的最后一個數(shù)組元素的地址。數(shù)組這時是連續(xù)分配的。

Outer LDR r1,=src:將src地址即數(shù)組元素首地址賦值給R1

Inner LDR r2,[r1] :將存儲器地址為r1的字數(shù)據(jù)讀入r2
LDR r3,[r1,#4]:將存儲器地址為R1+4的字數(shù)據(jù)讀入R3
CMP r2,r3 :比較R2,R3
STRGT r3,[r1]:若(有符號數(shù))大于,則將R3中的字數(shù)據(jù)寫入以R1為地址的存儲器中
STRGT r2,[r1,#4]:若大于,則將R2中的字數(shù)據(jù)寫入以R1+4為地址的存儲器中
ADD r1,r1,#4:R1+4賦值給R1
CMP r1,r6:R1與R6比較
BLT Inner:若是有符號數(shù)小于,即R1
ADD r4,r4,#4:R4+4賦值給R4
CMP r4,#len:R4與len比較
SUBLE r6,r6,#4 :若有符號數(shù)小于或等于,則R6-4賦值給R6
BLE Outer :若有符號數(shù)小于或等于,則跳轉到Outer
Stop MOV r0,#0x18 , stop一段是用來是程序退出的,第一個語句“MOV r0,#0x18”將r0賦值為0x18,這個立即數(shù)對應于宏angel_SWIreason_ReportException。表示r1中存放的執(zhí)行狀態(tài)。語句“LDR r1,=0x20026”將r1的值設置成ADP_Stopped_ApplicationExit,該宏表示程序正常退出。然后使用SWI,語句“SWI 0x123456”結束程序,將CPU的控制權交回調試器手中。

LDR r1,=0x20026
SWI 0x123456

AREA Array,DATA,READWRITE
src DCD 2,4,10,8,14,1,20 :數(shù)據(jù)定義偽指令DCD表示用于分配一片連續(xù)的字存儲單元并用指定的數(shù)據(jù)初始化
len EQU 7*4 :這里的4是4個字節(jié)。即是32位。因為ARM7TDMI是32位ARM指令集。

END:結束代碼

代碼很清晰。思想很對。執(zhí)行結果貌似也很對。




可是詳細看看不對。數(shù)組的起始地址是0x00008058(此時的r6的值。r6初值為起始地址加len,經(jīng)過程序的遞減后變成了起始地址),那么冒泡完后0x00008058存儲的應該是01 00 00 00(按ADS里面的內存內容顯示格式),可是此時存儲的是00 E8 00 E8,從0x0000805c開始才是冒泡排序后的結果。程序肯定是有問題的。既然要找問題,那就單步調試吧。

這里面忘了介紹怎么看內存里面存的內容了。之前我一直找不著。因為點擊出現(xiàn)內存框框時,沒有注意到有個start adreess。比如這個程序里面的數(shù)組起始地址是0x0000805c,那么我們把start address通過點擊遞加設為0x8000。

接著單步調試。


這是第一次排序的結果。明顯不對。因為這個數(shù)組里面排序最大的是沉到低了,可是數(shù)0x00E800E8也參合進來,冒泡到最大的數(shù)的前面了。這個不對。也就是這個程序的內循環(huán)控制不對。

改正的話其實很簡單。就是程序里內循環(huán)對比較了一次。這里我采用的方法是len定義為6*4,把len理解為偏移量應該是更合適的吧。第一個數(shù)的地址為0x00008058,那么最后一個數(shù)的地址加上6*4 = 24的偏移量,應該是0x00008070。這樣才是正確的數(shù)組地址。


關鍵詞: arm匯編冒泡排

評論


技術專區(qū)

關閉