ARM所有常用指令的實例與說明
程序跳轉(zhuǎn)類指令:
====================
BX,
語法: bx Rn
此指令執(zhí)行程序跳轉(zhuǎn),執(zhí)行后,cpu從Rn這個寄存器里面所存的內(nèi)存地址處開始繼續(xù)執(zhí)行。由于是跳轉(zhuǎn),因此也會同時刷新管道線。另外,如果此Rn的最低位為1的話,隨后的指令將被譯作thumb指令,如果最低位為0的話,隨后的指令將被譯作arm32位指令。因此,此指令可以用于在32位arm指令與16位thumb指令之間進行跳轉(zhuǎn)。
32位代碼轉(zhuǎn)入16位代碼執(zhí)行:
16位代碼轉(zhuǎn)入32位代碼執(zhí)行:
B, BL 指令,
語法: 指令 表達式/label
B指令就直接跳轉(zhuǎn)指定的地方,bl跳轉(zhuǎn)到指定的地方之前還要把當前pc保存在lr寄存器里面。
die_loop:
b die_loop這樣就構(gòu)成了死循環(huán)
bl add保存當前pc到lr,然后調(diào)用add函數(shù),
數(shù)據(jù)處理類指令:
====================
mov, mvn指令:
語法: 指令 目標寄存器, 操作數(shù)
mov指令把操作數(shù)拷貝到目標寄存器里面。操作數(shù)可以是:寄存器,或者立即數(shù)表達式,
例如:
mov r0, r1# 把r1賦給r0
mov r2, #7
mov r0, r1, LSL r2把r1左移r2位后賦給r0
mov r2, #100# 把立即數(shù)100賦給r2
mvn指令把操作數(shù)按位取反之后把值賦給目標寄存器。
例如:
mov r0, r1# 表示把r1里面的值按位取反后賦給r0
cmp, cmn, teq, tst, 指令:
語法: 指令 寄存器, 操作數(shù)
操作數(shù)可以是:寄存器,或者立即數(shù)表達式
這四條指令都是讓后面的寄存器于操作數(shù)執(zhí)行相應(yīng)的操作后根據(jù)結(jié)果設(shè)定cpsr寄存器里面的相應(yīng)位的值。
cmp指令把寄存器和操作數(shù)相減,根據(jù)結(jié)果設(shè)定cpsr。用于比較大小。
例如:循環(huán)100次
mov r0, #0
loop100:
add r0, r0, #1
cmp r0, #100
ble loop100
cmn指令把寄存器和操作數(shù)想加,根據(jù)結(jié)果設(shè)定cpsr。用于看兩個數(shù)只和會不會有進位。
teq指令把寄存器和操作數(shù)進行按位異或,根據(jù)結(jié)果設(shè)定cpsr。用于測試兩個數(shù)是否相等。
tst指令把寄存器和操作數(shù)進行按位相與,根據(jù)結(jié)果設(shè)定cpsr。用于測試某位是否為1。
這四條指令在執(zhí)行期間都只是對寄存器和操作數(shù)進行操作,并不回寫。
and, eor, sub, rsb, add, adc, sbc, rsc, orr, bic指令:
語法:指令 Rd, Rn, Op2
操作數(shù)可以是:寄存器,立即數(shù)
and 指令對Rn和Op2按位與操作之后把結(jié)果賦值給Rd.
eor 指令對Rn和Op2按位異或操作之后把結(jié)果賦值給Rd.
sub 指令對Rn和Op2進行減操作之后把結(jié)果賦值給Rd.
rsb 指令對Op2和Rn進行減操作之后把結(jié)果賦值給Rd.
add 指令對Rn和Op2進行加操作之后把結(jié)果賦值給Rd.
adc 指令對Rn和Op2加操作并且加上cpsr寄存器中的C位的值之后把結(jié)果賦值給Rd.
sbc 指令執(zhí)行Rn-op2-1+進位位之后把結(jié)果賦值給Rd。
rsc 指令執(zhí)行Op2-Rn-1+近位位之后把結(jié)果賦值給Rd.
orr 指令對Rn和Op2按位或操作之后把結(jié)果賦值給Rd.
bic 指令執(zhí)行對Op2先按位取反之后再與Rn進行按位與操作,之后把結(jié)果賦值給Rd,用于對Rd中的某位置0.
mrs, msr指令:
語法: mrs Rd,
msr
msr
msr
psr可以是cpsr, spsr, mrs用于讀取psr寄存器里面的值然后賦值給Rd.
msr用于存儲Rm寄存器里面的值進入psr里面。
msr
mul, mla指令:
語法:mul Rd, Rm, Rs
mla Rd, Rm, Rs, Rn
mul指令對Rm和Rs執(zhí)行乘操作之后把值賦給Rd。Rd = Rm * Rs.
mla指令對Rd和Rs執(zhí)行乘操作之后并加上Rn后賦值給Rd. Rd = Rm * Rs + Rn。
mull, mlal指令:
語法:umull RdLo, RdHi, Rm, Rs:把Rm和Rs當作32位無符號數(shù)執(zhí)行乘法操作,然后把結(jié)果的低32位賦給RdLo, 高32位賦給RdHi
umlal RdLo, RdHi, Rm, Rs:把Rm和Rs當作32位無符號數(shù)執(zhí)行乘法操作,再加上由RdHi和RdLo組成的64位數(shù),然后把結(jié)果的低32位賦給RdLo, 高32位賦給RdHi
smull RdLo, RdHi, Rm, Rs:把Rm和Rs當作32位有符號數(shù)執(zhí)行乘法操作,然后把結(jié)果的低32位賦給RdLo, 高32位賦給RdHi
smlal RdLo, RdHi, Rm, Rs:把Rm和Rs當作32位有符號數(shù)執(zhí)行乘法操作,再加上由RdHi和RdLo組成的64位數(shù),然后把結(jié)果的低32位賦給RdLo, 高32位賦給RdHi
ldr, str指令:
語法:
ldr用于從內(nèi)存中加載數(shù)據(jù)到寄存器。
str用于存儲寄存器中的數(shù)據(jù)到內(nèi)存中。
例子:
.LC:
ldr r0, .LC:表示把.LC所處內(nèi)存地址里面的4個字節(jié)值賦給r0(這種情況需要此命令與標簽在同一段內(nèi))
ldr r0, =.LC:表示直接把.LC所處的地址賦給r0
ldr r0, [r1] : 表示把把r1所代表的內(nèi)存地址里面的值賦給r0
ldr r0, [r1, #8] : 表示r1加上8個字節(jié)代表的內(nèi)存地址里面的值賦給r0
ldr r0, [r1, #8]!: 表示r1加上8個字節(jié)代表的內(nèi)存地址里面的值賦給r0, 然后把r1 = r1 + 8
ldr r0, [r1], #4: 表示把r1所代表的內(nèi)存地址里面的值賦給r0, 之后, r1 += 4
ldr r0, [r1, r2, LSL #2] :表示把r1+r2 * 4所代表的內(nèi)存地址里面的值賦給r0
str r0, [r1, r2]: 把r1 + r2所代表的內(nèi)存地址里面的值賦入r0
str r0, [r1, r2]!: 把r1 + r2所代表的內(nèi)存地址里面的值賦入r0, r1 = r1 + r2
ldm, stm指令:
語法:
Rlist, 表示寄存器列表。比如{r0, r2, r5-r7,r9 }
{!}, 表示執(zhí)行完ldm或stm之后是否對Rn進行回寫。
{^}, 表示恢復spsr中的值到cpsr。(一般用于返回以前模式)
寄存器列表中的數(shù)據(jù)在內(nèi)存中將被存放的順序為低寄存器對應(yīng)低內(nèi)存地址的順序存放。
stm操作始終與所指定的棧的方向保持相同,ldm相反。stm就相當于壓棧,ldm就相當于退棧。
stm表示把寄存器的數(shù)據(jù)存入內(nèi)存
ldm表示把內(nèi)存中的數(shù)據(jù)加載到寄存器上。
例如:
ldmfdsp, {r0,r1,r2} 表示把sp所指的內(nèi)存地址開始的12個字節(jié)分別賦值給r0,r1,r2。
ldmfdsp!, {r0,r1,r2} 表示把sp所指的內(nèi)存地址開始的12個字節(jié)分別賦值給r0,r1,r2,之后sp = sp + 12
ldmfd sp!, {r15}^表示把sp棧所指的4個字節(jié)里面的值賦給r15, 同時把spsr賦值給cpsr,并且sp += 4
stmfd sp, {r0, r1, r2} 表示把r2,r1,r0按照sp所指地址遞減存儲。也就相當于下面3條指令:
str r2, [sp, #-4]
str r1, [sp, #-8]
str r0, [sp, #-12]
stmfd sp!, {r0, r1, r2} 表示把r2,r1,r0按照sp所指地址遞減存儲。并且把sp = sp - 12,也就相當于下面4條指令:
str r2, [sp, #-4]
str r1, [sp, #-8]
str r0, [sp, #-12]
sub sp, sp, #12
特殊用法:
stmfd sp!, {r0-r15}^ : 表示把用戶模式下面的r0-r15寄存器存在當前模式下面的sp所指向的棧中。
stmfd sp!, {r0-r14}^ : 表示把用戶模式下面的r0-r14寄存器存在當前模式下面的sp所指向的棧中。用于進程切換的時候保存用戶模式下面的寄存器。
ldmfd sp!, {r0-r14}^ : 寄存器列表這里面不帶有r15(pc), 表示把當前模式下面sp所指的棧中的15個int拷貝用戶模式下面的r0-r14。這個用于恢復進程狀態(tài)。
swp指令:
語法:
swp指令執(zhí)行單字節(jié)或單字的內(nèi)存于寄存器的數(shù)據(jù)交換原子操作。把rn所指內(nèi)存里面的值賦值給Rd, 然后把R1存入R2所指的內(nèi)存。經(jīng)常用于內(nèi)核中實現(xiàn)控制互斥與信號等功能。
例如:
swp r0, r1,[r2]:表示把r2所指的內(nèi)存地址里面的值賦值給r0, 然后把r1存入r2所指內(nèi)存地址。相當于下面2條指令的原子操作。
ldr r0, [r2]
str r1, [r2]
評論