深圳b2b網(wǎng)站建設(shè)排名南寧seo優(yōu)勢(shì)
1.基礎(chǔ)讀寫指令
寫內(nèi)存指令:STR
@ MOV R1, #0xFF000000@ MOV R2, #0x40000000@ STR R1, [R2] @ 將R1寄存器中的數(shù)據(jù)寫入到R2指向的內(nèi)存空間
?需注意,此命令是將R1中的數(shù)據(jù)寫給R2所指向的內(nèi)存空間,而不是直接把R1的數(shù)據(jù)賦給R2,R2寄存器中存放的是數(shù)據(jù)要被寫入的內(nèi)存的起始地址,由于使用的是STR指令,所以R2中存放的地址時(shí)不會(huì)改變的,如果后續(xù)再次向R2所指向的內(nèi)存中寫數(shù)據(jù),則原來(lái)的數(shù)據(jù)會(huì)被覆蓋。
讀內(nèi)存指令:LDR
@ MOV R1, #0xFF000000@ MOV R2, #0x40000000@ LDR R3, [R2]@ 將R2指向的內(nèi)存空間中的數(shù)據(jù)讀取到R3寄存器
原理基本同上,是將R2存放的地址指向的空間中的數(shù)據(jù)讀取到R3寄存器中
讀寫指定的數(shù)據(jù)類型:
? 在ARM中有三種數(shù)據(jù)類型,Byte類型占一個(gè)字節(jié),Halfword類型占兩個(gè)字節(jié),Word類型占四個(gè)字節(jié),如果我們指向讀取某個(gè)數(shù)據(jù)類型的數(shù)據(jù),只需要在讀寫指令后加上后綴即可,示例如下:
@ MOV R1, #0xFFFFFFFF@ MOV R2, #0x40000000@Byte類型:@ STRB R1, [R2]@ 因?yàn)锽yte類型占一個(gè)字節(jié)也就是8bit,@所以指令的含義是將R1寄存器中的數(shù)據(jù)的前8位寫入到R2指向的內(nèi)存空間@Halfword類型:@ STRH R1, [R2] @ 將R1寄存器中的數(shù)據(jù)的前16位寫入到R2指向的內(nèi)存空間@Word類型:@ STR R1, [R2] @ 將R1寄存器中的數(shù)據(jù)的前32位寫入到R2指向的內(nèi)存空間@ LDR指令同樣支持以上后綴,并且含義相同
2.基址加變址尋址:
前索引和后索引:
? ? ? ? 由其定義可知,我們要操作的地址變成了 基本地址 + 可變地址,如下程序所示,要進(jìn)行讀寫操作的內(nèi)存的地址變成了中括號(hào)中的數(shù)據(jù)的和。?
@ MOV R1, #0xFFFFFFFF@ MOV R2, #0x40000000@ MOV R3, #4@ STR R1, [R2,R3]@ 將R1寄存器中的數(shù)據(jù)寫入到R2+R3指向的內(nèi)存空間,也就是0x40000004指向的地址空間@ STR R1, [R2,R3,LSL #1]@ 將R1寄存器中的數(shù)據(jù)寫入到R2+(R3<<1)指向的內(nèi)存空間
? ? ? ? 上面代碼中將可變地址R3寫入中括號(hào)里的方法叫做基址加變址尋址的前索引方式,而將其寫在中括號(hào)后為后索引方式,他們倆的含義如下:
@ 前索引@ MOV R1, #0xFFFFFFFF@ MOV R2, #0x40000000@ STR R1, [R2,#8]@ 將R1寄存器中的數(shù)據(jù)寫入到R2+8指向的內(nèi)存空間@ 后索引@ MOV R1, #0xFFFFFFFF@ MOV R2, #0x40000000@ STR R1, [R2],#8@ 將R1寄存器中的數(shù)據(jù)寫入到R2指向的內(nèi)存空間,然后R2自增8
自動(dòng)索引:
? 除了他們倆之外,還有一種索引叫做自動(dòng)索引,其定義如下:
@ MOV R1, #0xFFFFFFFF@ MOV R2, #0x40000000@ STR R1, [R2,#8]!@ 將R1寄存器中的數(shù)據(jù)寫入到R2+8指向的內(nèi)存空間,然后R2自增8
????????需注意,自動(dòng)索引! 的位置是不能改變的并且 必須要是英文的?
3.多寄存器內(nèi)存訪問(wèn)指令:
多寄存器內(nèi)存訪問(wèn)指令,其含義就是同時(shí)讀寫多個(gè)寄存器中的數(shù)據(jù),示例如下:
@ MOV R1, #1@ MOV R2, #2@ MOV R3, #3@ MOV R4, #4@ MOV R11,#0x40000020@ STM R11,{R1-R4}@ 將R1-R4寄存器中的數(shù)據(jù)寫入到以R11為起始地址的內(nèi)存空間中@ LDM R11,{R6-R9}@ 將以R11為起始地址的內(nèi)存空間中的數(shù)據(jù)讀取到R6-R9寄存器中
? 與單獨(dú)讀寫一個(gè)寄存器的數(shù)據(jù)相比,指令由STR和LDR變成了STM和LDM,其存放 要進(jìn)行讀或?qū)懖僮鞯牡刂?的寄存器變成了目標(biāo)寄存器,也就是作為了指令后的第一個(gè)參數(shù),要被讀入或?qū)懙臄?shù)據(jù)所要存放的寄存器被放在一個(gè)大括號(hào)中,ARM會(huì)依次將其讀取或?qū)懭氲较鄳?yīng)的位置,大括號(hào)中的寫法也可以使用逗號(hào)隔開,例如{R1,R2,R3,R4},但是無(wú)論其順序怎么改變,他在進(jìn)行操作時(shí)都是低地址對(duì)應(yīng)小號(hào)的寄存器,例如上邊程序的寫指令即使寫成 STM R11,{R2,R1,R4,R3}? 他在寫入到R11為起始地址的內(nèi)存空間中時(shí)也是先將R1存放到底地址0x4000020當(dāng)中,讀指令也是如此。
自動(dòng)索引也同樣適用于多寄存器內(nèi)存訪問(wèn)指令,只是感嘆號(hào)位置發(fā)生了改變,具體如下:
@ STM R11!,{R1-R4}
執(zhí)行完這條指令后,R1-R4會(huì)被依次寫入在R11指向的地址處,因?yàn)閷懭肓怂膫€(gè)數(shù)據(jù),所以R11所儲(chǔ)存的地址會(huì)自增16個(gè)字節(jié)。
?多寄存器內(nèi)存訪問(wèn)指令的尋址方式:
?STM指令與LDM指令有四個(gè)后綴,分別為IA,IB,DA,DB,下面的這些都是在其有自動(dòng)索引時(shí)的解釋,其意義分別為:
- STMIA R11! :先儲(chǔ)存數(shù)據(jù),然后地址在增加
- STMIB?R11! : 地址先增加,然后再儲(chǔ)存數(shù)據(jù)
- STMDA?R11! :先儲(chǔ)存數(shù)據(jù),然后地址遞減
- STMDB?R11! :地址先減少,然后再儲(chǔ)存數(shù)據(jù)
如下圖所示,我用大白話形容一下,IA就是先把你要寫入的第一條數(shù)據(jù)先寫進(jìn)R11存放的地址中,然后再將R11的地址增加去存放下一個(gè)數(shù)據(jù),直到數(shù)據(jù)全部存完后R11的地址在增加一次指向?qū)懭氲淖詈笠粋€(gè)數(shù)據(jù)的下一個(gè)地址,IB就是先讓R11的地址增加一次,然后再開始寫入數(shù)據(jù),最后R11的地址會(huì)指向所寫入的最后一條數(shù)據(jù)。DA和DB只是存儲(chǔ)方向相反而已,方式是相同的,注意寫入數(shù)據(jù)和增加地址的過(guò)程是一一對(duì)應(yīng)的,寫一條就要加一次,數(shù)據(jù)是一條一條存放到內(nèi)存中而不是一下全放進(jìn)去然后地址一次性增加。
@ MOV R1, #1@ MOV R2, #2@ MOV R3, #3@ MOV R4, #4@ MOV R11,#0x40000020@ STMIA R11!,{R1-R4}@ 先存儲(chǔ)數(shù)據(jù),后增長(zhǎng)地址@ STMIB R11!,{R1-R4}@ 先增長(zhǎng)地址,后存儲(chǔ)數(shù)據(jù)@ STMDA R11!,{R1-R4}@ 先存儲(chǔ)數(shù)據(jù),后遞減地址@ STMDB R11!,{R1-R4}@ 先遞減地址,后存儲(chǔ)數(shù)據(jù)
ARM使用的大多是
4.ARM棧的種類與使用:
概念:棧的本質(zhì)就是一段內(nèi)存,程序運(yùn)行時(shí)用于保存一些臨時(shí)數(shù)據(jù),如局部變量、函數(shù)的參數(shù)、返回值、以及程序跳轉(zhuǎn)時(shí)需要保護(hù)的寄存器等
棧的分類:
- 增棧:壓棧時(shí)棧指針越來(lái)越大,出棧時(shí)棧指針越來(lái)越小 ? ?
- 減棧:壓棧時(shí)棧指針越來(lái)越大,出棧時(shí)棧指針越來(lái)越小 ? ?
- 滿棧:棧指針指向最后一次壓入到棧中的數(shù)據(jù),壓棧時(shí)需要先移動(dòng)棧指針到相鄰位置然后再壓棧 ? ?
- 空棧:棧指針指向最后一次壓入到棧中的數(shù)據(jù)的相鄰位置,壓棧時(shí)可直接壓棧,之后需要將棧指針移動(dòng)到相鄰位置 ?
增減和空滿是組合在一起的,棧分為空增(EA)、空減(ED)、滿增(FA)、滿減(FD)四種,EA對(duì)應(yīng)上面的IA,ED對(duì)應(yīng)DA,FA對(duì)應(yīng)IB,FD對(duì)應(yīng)DB可以對(duì)應(yīng)ARM處理器一般使用滿減棧,所以對(duì)ARM的棧做存儲(chǔ)操作時(shí)可以直接使用FD后綴
葉子函數(shù):一個(gè)函數(shù)里沒(méi)有調(diào)用其他函數(shù),那么他就是葉子函數(shù)
匯編中進(jìn)行跳轉(zhuǎn)的過(guò)程就在下面代碼中,程序自己理解吧,等哪天我在把具體的步驟寫一下哈哈哈
示例:
@ MOV R1, #1@ MOV R2, #2@ MOV R3, #3@ MOV R4, #4@ MOV R11,#0x40000020@ STMFD R11!,{R1-R4}@ LDMFD R11!,{R6-R9}@ 棧的應(yīng)用舉例@ 1.葉子函數(shù)的調(diào)用過(guò)程舉例@ 初始化棧指針@ MOV SP, #0x40000020
@ MIAN:@ MOV R1, #3@ MOV R2, #5@ BL FUNC@ ADD R3, R1, R2@ B STOP@ FUNC:@ 壓棧保護(hù)現(xiàn)場(chǎng)@ STMFD SP!, {R1,R2}@ MOV R1, #10@ MOV R2, #20@ SUB R3, R2, R1@ 出?;謴?fù)現(xiàn)場(chǎng)@ LDMFD SP!, {R1,R2}@ MOV PC, LR@ 2.非葉子函數(shù)的調(diào)用過(guò)程舉例@ MOV SP, #0x40000020
@ MIAN:@ MOV R1, #3@ MOV R2, #5@ BL FUNC1@ ADD R3, R1, R2@ B STOP
@ FUNC1:@ STMFD SP!, {R1,R2,LR}@ MOV R1, #10@ MOV R2, #20@ BL FUNC2@ SUB R3, R2, R1@ LDMFD SP!, {R1,R2,LR}@ MOV PC, LR
@ FUNC2:@ STMFD SP!, {R1,R2}@ MOV R1, #7@ MOV R2, #8@ MUL R3, R1, R2@ LDMFD SP!, {R1,R2}@ MOV PC, LR@ 執(zhí)行葉子函數(shù)時(shí)不需要對(duì)LR壓棧保護(hù),執(zhí)行非葉子函數(shù)時(shí)需要對(duì)LR壓棧保護(hù)
?