ARM匯編指令學(xué)習(xí)(1) 實(shí)現(xiàn)數(shù)據(jù)塊拷貝
設(shè)計(jì)一段程序完成數(shù)據(jù)塊的,數(shù)據(jù)從源數(shù)據(jù)區(qū)snum到目標(biāo)數(shù)據(jù)區(qū)dnum,數(shù)據(jù)量大小為NUM字(1個(gè)字=4個(gè)字節(jié)),時(shí)以8個(gè)字為單位進(jìn)行,對(duì)于最后所剩不到8個(gè)字的數(shù)據(jù),以字為單位進(jìn)行。
本文引用地址:http://butianyuan.cn/article/201611/317764.htm程序清單:
1 ;==============================================================================2 ; blocks.s: 將數(shù)據(jù)從源數(shù)據(jù)區(qū)snum到目標(biāo)數(shù)據(jù)區(qū)dnum,數(shù)據(jù)量大小為NUM字3 ; 時(shí)以8個(gè)字為單位進(jìn)行,最后不夠8個(gè)字的數(shù)據(jù)按1個(gè)字為單位4 ;==============================================================================5 6 NUM EQU 20 ; NUM表示有20個(gè)字(80字節(jié))數(shù)據(jù),以字為單位,宏定義要頂格書(shū)寫(xiě)7 8 AREA Init, CODE, READONLY ; 定義一個(gè)代碼段,段名為Init,屬性為READONLY 9 CODE32 ; 告訴匯編編譯器后面的指令序列為32位的ARM指令,10 ; 該偽操作只是告訴編譯器后面指令的類型,其本身11 ; 并不進(jìn)行程序狀態(tài)切換12 ENTRY ; 指定程序的入口點(diǎn)13 14 15 ;變量的初始化16 START17 LDR R0, =SRC ; R0指向源數(shù)據(jù)區(qū)起始地址18 LDR R1, =DST ; R1指向目的數(shù)據(jù)區(qū)起始地址19 MOV R2, #NUM ; R2存放待數(shù)據(jù)量大小,以字為單位20 MOV SP, #0X400 ; 堆棧指針指向0X400,堆棧增長(zhǎng)模式由裝載指令的類型域確定 21 22 ;確定條件及保存現(xiàn)場(chǎng)23 BLKCOPY24 MOV R3, R2, LSR #3 ; 將R2中值除以8后的結(jié)果存放在R3,R3中值表示NUM中有多少個(gè)8字單元25 BEQ COPYWORDS ; 若Z=1(R3=0,數(shù)據(jù)少于1個(gè)8字單元),則跳轉(zhuǎn)到COPYWORDS處,運(yùn)行少于8字單元數(shù)據(jù)處理程序26 STMFD SP!, {R4-R11} ; 保存R4-R11的內(nèi)容到堆棧,并更新棧指針,F(xiàn)D:滿遞減堆棧,由此可知堆棧長(zhǎng)向27 28 ;8字單元數(shù)據(jù)主程序29 OCTCOPY30 LDMIA R0!, {R4-R11} ; 從R0所指的源數(shù)據(jù)區(qū)裝載8個(gè)字?jǐn)?shù)據(jù)到R4-R11中,每次裝載1個(gè)字后R0中地址加1,最后更新R0中地址31 STMIA R1!, {R4-R11} ; 將R4-R11的8個(gè)字?jǐn)?shù)據(jù)存入R1所指的目的數(shù)據(jù)區(qū),每次裝載1個(gè)字后R1中地址加1,最后更新R1中地址32 SUBS R3, R3, #1 ; 每一次,則R3=R3-1,表示已經(jīng)了1個(gè)8字單元,結(jié)果影響CPSR33 BNE OCTCOPY ; 若CPSR的Z=0(即運(yùn)算結(jié)果R3不等于0),跳轉(zhuǎn)到OCTCOPY,繼續(xù)下一個(gè)8字單元數(shù)據(jù)34 LDMFD SP!, {R4-R11} ; 將堆棧內(nèi)容恢復(fù)到R4-R11中,并更新堆棧指針,此時(shí)整8字單元數(shù)據(jù)已經(jīng)完成,且出棧模式應(yīng)和入棧模式一樣35 36 ;少于8字單元數(shù)據(jù)處理程序37 COPYWORDS38 ANDS R2,R2, #7 ; 得到NUM除以8后余數(shù),即未滿8字單元數(shù)據(jù)的字?jǐn)?shù)(1個(gè)字=4個(gè)字節(jié))39 BEQ STOP ; 若R2=0(NUM有整數(shù)個(gè)8字單元),則停止40 41 ;單字單元數(shù)據(jù)程序,用來(lái)處理不足8字單元數(shù)據(jù) 42 WORDCOPY43 LDR R3, [R0], #4 ; 將R0所指源數(shù)據(jù)區(qū)的4個(gè)字節(jié)(1個(gè)字)數(shù)據(jù)裝載至R3,然后R0=R0+444 STR R3, [R1], #4 ; 將R3中4個(gè)字節(jié)(1個(gè)字)數(shù)據(jù)存到R1所指目的數(shù)據(jù)區(qū),然后R1=R1+445 SUBS R2, R2, #1 ; 數(shù)據(jù)傳輸控制計(jì)數(shù)器減1(其總是小于8),成功一個(gè)字?jǐn)?shù)據(jù)46 BNE WORDCOPY ; 若R2不等于0,則轉(zhuǎn)到WORDCOPY,繼續(xù)下一個(gè)字?jǐn)?shù)據(jù)47 48 ;停止操作死循環(huán)49 STOP50 B STOP51 52 ;數(shù)據(jù)緩沖池53 LTORG ;聲明一個(gè)數(shù)據(jù)緩沖池的開(kāi)始,一般在代碼的最后面54 ;定義源數(shù)據(jù)區(qū),每個(gè)數(shù)據(jù)均是字型(占4個(gè)字節(jié))55 ;DCD,分配一段字內(nèi)存單元(分配的內(nèi)存是字對(duì)齊的),并用后續(xù)的數(shù)據(jù)初始化該段內(nèi)存56 SRC DCD 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4 57 58 ;定義目的數(shù)據(jù)區(qū),并初始化為059 DST DCD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,060 61 62 ;源程序結(jié)尾63 END
代碼使用ADS 1.2編譯后,即可使用AXD Debugger單步調(diào)試,可以很直觀的看到代碼的執(zhí)行結(jié)果。
評(píng)論