<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          arm匯編之冒泡排序

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

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

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




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

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

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

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

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

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

          LDR r1,=0x20026
          SWI 0x123456

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

          END:結(jié)束代碼

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




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

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

          接著單步調(diào)試。


          這是第一次排序的結(jié)果。明顯不對(duì)。因?yàn)檫@個(gè)數(shù)組里面排序最大的是沉到低了,可是數(shù)0x00E800E8也參合進(jìn)來(lái),冒泡到最大的數(shù)的前面了。這個(gè)不對(duì)。也就是這個(gè)程序的內(nèi)循環(huán)控制不對(duì)。

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


          關(guān)鍵詞: arm匯編冒泡排

          評(píng)論


          技術(shù)專區(qū)

          關(guān)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();