ARM:特殊功能寄存器、Load/Store内存读写指令、栈操作指令
1.特殊功能寄存器讀寫指令
msr -->>將普通寄存器中的數(shù)據(jù)寫到特殊寄存器中
mrs -->>將特殊寄存器中的數(shù)據(jù)寫到普通寄存器中
注:特殊寄存器 cpsr 的讀寫訪問(wèn)只能使用 msr 和 mrs 指令
.text /* 代碼段 */ /* 將_start 聲明為一個(gè)全局的函數(shù), _start表示匯編程序的入口 */ .globl _start /* globl 與 global 效果一樣 */_start: /* 標(biāo)簽 : 類似于C語(yǔ)言的函數(shù)的名字, 表示函數(shù)的入口地址 *//*格式msr cpsr, 普通寄存器/立即數(shù) @ cpsr = 普通寄存器/立即數(shù)mrs Rd, cpsr @ Rd = cpsr*/@ 系統(tǒng)上電默認(rèn)是svc 模式@ 修改系統(tǒng)模式到用戶模式@ svc模式(10011) -->> 用戶模式(10000)@ 1101 0011 -->> 1101 0000@ 1.通過(guò) msr 直接修改@msr cpsr, #0xd0@ 2.通過(guò)位運(yùn)算的方式mrs r0, cpsrbic r0, r0, #0x1f @將[4:0]位清零orr r0, r0, #0x10msr cpsr, r0stop:b stop .end2.Load/Store內(nèi)存讀寫指令
2.1單寄存器操作指令
ldr -->>將內(nèi)存中的數(shù)據(jù)讀到普通寄存器中,讀4個(gè)字節(jié)的大小
str -->>將普通寄存器中的數(shù)據(jù)寫到內(nèi)存中,寫4個(gè)字節(jié)的大小
ldrh -->>將內(nèi)存中的數(shù)據(jù)讀到普通寄存器中,讀2個(gè)字節(jié)的大小
strh -->>將普通寄存器中的數(shù)據(jù)寫到內(nèi)存中,寫2個(gè)字節(jié)的大小
ldrb -->>將內(nèi)存中的數(shù)據(jù)讀到普通寄存器中,讀1個(gè)字節(jié)的大小
strb -->>將普通寄存器中的數(shù)據(jù)寫到內(nèi)存中,寫1個(gè)字節(jié)的大小
.text /* 代碼段 */ /* 將_start 聲明為一個(gè)全局的函數(shù), _start表示匯編程序的入口 */ .globl _start /* globl 與 global 效果一樣 */_start: /* 標(biāo)簽 : 類似于C語(yǔ)言的函數(shù)的名字, 表示函數(shù)的入口地址 *//*其他用法:@ 將[Rm + offset]地址中的內(nèi)容讀到Rd寄存器中,Rm中的值不變ldr/ldrh/ldrb Rd, [Rm, #offset] @ 將[Rm]地址中的內(nèi)容讀到Rd寄存器中, 同時(shí)更新Rm中的地址:Rm=Rm+offsetldr/ldrh/ldrb Rd, [Rm], #offset @ 將[Rm + offset]地址中的內(nèi)容讀到Rd寄存器中,同時(shí)更新Rm中的地址:Rm=Rm+offset@ ! : 更新地址ldr/ldrh/ldrb Rd, [Rm, #offset]! @ 將Rn寄存器中的數(shù)據(jù)寫到[Rm + offset]地址中,Rm中的值不變str/strh/strb Rn, [Rm, #offset]@ 將Rn寄存器中的數(shù)據(jù)寫到[Rm]地址中,同時(shí)更新Rm中的地址:Rm=Rm+offsetstr/strh/strb Rn, [Rm], #offset@ 將Rn寄存器中的數(shù)據(jù)寫到[Rm + offset]地址中,同時(shí)更新Rm中的地址:Rm=Rm+offsetstr/strh/strb Rn, [Rm, #offset]!offset : 偏移地址,偏移地址的大小是Load/Store指令可訪問(wèn)空間大小的整數(shù)倍。*/.if 0ldr r0, =0x12345678ldr r1, =0x40000800@ 將 r0 中的數(shù)據(jù)寫到 [r1] 指向的地址空間str r0, [r1]@ 將 [r1] 指向的地址空間的數(shù)據(jù)讀到r2寄存器中l(wèi)dr r2, [r1].endifldr r0, =0x40000800ldr r1, =0x11111111ldr r2, =0x22222222ldr r3, =0x33333333@ 將r1中的數(shù)據(jù)寫到[r0+4]地址中,r0中的值不變@ [0x40000804] = 0x11111111 , r0 = 0x40000800str r1, [r0, #4]@ 將r2中的數(shù)據(jù)寫到[r0]地址中,同時(shí)更新r0中的地址,r0=r0+4@ [0x40000800] = 0x22222222 , r0 = 0x40000804str r2, [r0], #4@ 將r1中的數(shù)據(jù)寫到[r0+4]地址中,同時(shí)更新r0中的地址,r0=r0+4@ [0x40000808] = 0x33333333 , r0 = 0x40000808str r3, [r0, #4]!stop:b stop .end執(zhí)行結(jié)果:
2.2多寄存器操作指令(ldm、stm)
.text /* 代碼段 */ /* 將_start 聲明為一個(gè)全局的函數(shù), _start表示匯編程序的入口 */ .globl _start /* globl 與 global 效果一樣 */_start: /* 標(biāo)簽 : 類似于C語(yǔ)言的函數(shù)的名字, 表示函數(shù)的入口地址 *//*ldm Rm, {寄存器列表}將Rm指向的連續(xù)的地址空間中的數(shù)據(jù)讀到寄存器列表的每個(gè)寄存器中stm Rm, {寄存器列表}將寄存器列表中的每個(gè)寄存器中的數(shù)據(jù)寫到Rm指向的連續(xù)的地址空間中使用注意:1. Rm寄存器中的數(shù)據(jù)被當(dāng)成一個(gè)地址看待2. 寄存器列表中的寄存器如果是連續(xù)的則使用"-"隔開(kāi);3. 寄存器列表中的寄存器如果不連續(xù)則使用","隔開(kāi);4. 寄存器列表中的寄存器要求從小到大依次書(shū)寫,如果從大到小書(shū)寫,要求依次用逗號(hào)隔開(kāi)書(shū)寫,但編譯器會(huì)報(bào)警告。*/@ 不管寄存器列表中的寄存器的順序如何書(shū)寫,@ 永遠(yuǎn)都是小編號(hào)的寄存器對(duì)應(yīng)低地址;@ 大編號(hào)的寄存器對(duì)應(yīng)高地址ldr r0, =0x40000800ldr r1, =0x11111111ldr r2, =0x22222222ldr r3, =0x33333333ldr r4, =0x44444444@ 將r1-r4寄存器中的數(shù)據(jù)寫到r0指向的連續(xù)的16字節(jié)空間中stm r0, {r1-r4}@ 將r0指向的連續(xù)的16字節(jié)空間的數(shù)據(jù)讀到r5-r8中l(wèi)dm r0, {r5-r7,r8}stop:b stop .end執(zhí)行結(jié)果:
?3.棧操作指令
1> 增棧: 壓棧之后,棧指針向高地址方向移動(dòng)。
2> 減棧: 壓棧之后,棧指針向低地址方向移動(dòng)。
3> 空棧: 當(dāng)前棧指針指向的空間沒(méi)有有效的數(shù)據(jù),因此可以先壓棧,壓棧之后棧指針指向的空間就有有效的數(shù)據(jù),因此需要移動(dòng)棧指針,讓棧指針指向一個(gè)沒(méi)有有效數(shù)據(jù)的空間。
4> 滿棧: 棧指針指向的空間有有效的數(shù)據(jù),需要先移動(dòng)棧指針,讓棧指針指向一個(gè)空的位置,在進(jìn)行壓棧的操作,壓制之后此時(shí)棧指針指向的空間又有有效的數(shù)據(jù)。
3.1棧的操作方式
棧的操作方式都是組合來(lái)使用的
滿增棧 : Full Ascending -----> stmfa/ldmfs
滿減棧 : Full Descending -----> stmfd/ldmfd
空增棧 : Empty Ascending -----> stmea/ldmea
空減棧 : Empty Descending -----> stmed/ldmed
ARM處理器默認(rèn)采用的是滿減棧,ARM指令集本身是支持以上4種棧的操作方式的所有的指令。
.text /* 代碼段 */ /* 將_start 聲明為一個(gè)全局的函數(shù), _start表示匯編程序的入口 */ .globl _start /* globl 與 global 效果一樣 */_start: /* 標(biāo)簽 : 類似于C語(yǔ)言的函數(shù)的名字, 表示函數(shù)的入口地址 *//*指令格式ldmfd sp!, {寄存器列表}將sp指向的棧空間中的數(shù)據(jù)讀到寄存器列表的每個(gè)寄存器中stmfd sp!, {寄存器列表}將寄存器列表中的每個(gè)寄存器中的數(shù)據(jù)寫到sp指向的棧空間中使用注意:0. ! : 壓棧和出棧之后都需要更新棧指針1. sp寄存器中的數(shù)據(jù)被當(dāng)成一個(gè)棧空間的地址看待2. 寄存器列表中的寄存器如果是連續(xù)的則使用"-"隔開(kāi);3. 寄存器列表中的寄存器如果不連續(xù)則使用","隔開(kāi);4. 寄存器列表中的寄存器要求從小到大依次書(shū)寫,如果從大到小書(shū)寫,要求依次用逗號(hào)隔開(kāi)書(shū)寫,編譯器會(huì)報(bào)警告。*/ldr sp, =0x40000800 @ 初始化sp的地址mov r0, #1mov r1, #2bl add_func1add r2, r0, r1nopb stopadd_func1:stmfd sp!, {r0-r1, lr}mov r0, #3mov r1, #4bl add_funcadd r3, r0, r1ldmfd sp!, {r0-r1, lr} @ 也可以寫成ldmfd sp!, {r0-r1, pc}mov pc, lr add_func:stmfd sp!, {r0,r1}mov r0, #5mov r1, #6add r4, r0, r1ldmfd sp!, {r0,r1}mov pc, lrstop:b stop .end執(zhí)行結(jié)果;
?
總結(jié)
以上是生活随笔為你收集整理的ARM:特殊功能寄存器、Load/Store内存读写指令、栈操作指令的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: (ICCV-2021)用于步态识别的3D
- 下一篇: Dynamics 365(online)