新聞中心

EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > ARM所有常用指令的實(shí)例與說明

ARM所有常用指令的實(shí)例與說明

作者: 時(shí)間:2016-11-10 來源:網(wǎng)絡(luò) 收藏
ARM所有常用指令的實(shí)例與說明:


程序跳轉(zhuǎn)類指令:
====================

本文引用地址:http://m.butianyuan.cn/article/201611/317564.htm


BX,
語法: bx Rn

此指令執(zhí)行程序跳轉(zhuǎn),執(zhí)行后,cpu從Rn這個(gè)寄存器里面所存的內(nèi)存地址處開始繼續(xù)執(zhí)行。由于是跳轉(zhuǎn),因此也會(huì)同時(shí)刷新管道線。另外,如果此Rn的最低位為1的話,隨后的指令將被譯作thumb指令,如果最低位為0的話,隨后的指令將被譯作arm32位指令。因此,此指令可以用于在32位arm指令與16位thumb指令之間進(jìn)行跳轉(zhuǎn)。

32位代碼轉(zhuǎn)入16位代碼執(zhí)行:

16位代碼轉(zhuǎn)入32位代碼執(zhí)行:


B, BL 指令,
語法: 指令 表達(dá)式/label

B指令就直接跳轉(zhuǎn)指定的地方,bl跳轉(zhuǎn)到指定的地方之前還要把當(dāng)前pc保存在lr寄存器里面。

die_loop:
b die_loop這樣就構(gòu)成了死循環(huán)

bl add保存當(dāng)前pc到lr,然后調(diào)用add函數(shù),

數(shù)據(jù)處理類指令:
====================

mov, mvn指令:
語法: 指令 目標(biāo)寄存器, 操作數(shù)

mov指令把操作數(shù)拷貝到目標(biāo)寄存器里面。操作數(shù)可以是:寄存器,或者立即數(shù)表達(dá)式,

例如:
mov r0, r1# 把r1賦給r0
mov r2, #7
mov r0, r1, LSL r2把r1左移r2位后賦給r0
mov r2, #100# 把立即數(shù)100賦給r2

mvn指令把操作數(shù)按位取反之后把值賦給目標(biāo)寄存器。

例如:
mov r0, r1# 表示把r1里面的值按位取反后賦給r0


cmp, cmn, teq, tst, 指令:
語法: 指令 寄存器, 操作數(shù)

操作數(shù)可以是:寄存器,或者立即數(shù)表達(dá)式
這四條指令都是讓后面的寄存器于操作數(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。用于看兩個(gè)數(shù)只和會(huì)不會(huì)有進(jìn)位。
teq指令把寄存器和操作數(shù)進(jìn)行按位異或,根據(jù)結(jié)果設(shè)定cpsr。用于測(cè)試兩個(gè)數(shù)是否相等。
tst指令把寄存器和操作數(shù)進(jìn)行按位相與,根據(jù)結(jié)果設(shè)定cpsr。用于測(cè)試某位是否為1。

這四條指令在執(zhí)行期間都只是對(duì)寄存器和操作數(shù)進(jìn)行操作,并不回寫。


and, eor, sub, rsb, add, adc, sbc, rsc, orr, bic指令:

語法:指令 Rd, Rn, Op2

操作數(shù)可以是:寄存器,立即數(shù)

and 指令對(duì)Rn和Op2按位與操作之后把結(jié)果賦值給Rd.
eor 指令對(duì)Rn和Op2按位異或操作之后把結(jié)果賦值給Rd.
sub 指令對(duì)Rn和Op2進(jìn)行減操作之后把結(jié)果賦值給Rd.
rsb 指令對(duì)Op2和Rn進(jìn)行減操作之后把結(jié)果賦值給Rd.
add 指令對(duì)Rn和Op2進(jìn)行加操作之后把結(jié)果賦值給Rd.
adc 指令對(duì)Rn和Op2加操作并且加上cpsr寄存器中的C位的值之后把結(jié)果賦值給Rd.
sbc 指令執(zhí)行Rn-op2-1+進(jìn)位位之后把結(jié)果賦值給Rd。
rsc 指令執(zhí)行Op2-Rn-1+近位位之后把結(jié)果賦值給Rd.
orr 指令對(duì)Rn和Op2按位或操作之后把結(jié)果賦值給Rd.
bic 指令執(zhí)行對(duì)Op2先按位取反之后再與Rn進(jìn)行按位與操作,之后把結(jié)果賦值給Rd,用于對(duì)Rd中的某位置0.


mrs, msr指令:
語法: mrs Rd,
msr , Rm
msr , Rm
msr , #expression

psr可以是cpsr, spsr, mrs用于讀取psr寄存器里面的值然后賦值給Rd.
msr用于存儲(chǔ)Rm寄存器里面的值進(jìn)入psr里面。
msr , Rm只修改psr里面的標(biāo)志位。


mul, mla指令:
語法:mul Rd, Rm, Rs
mla Rd, Rm, Rs, Rn

mul指令對(duì)Rm和Rs執(zhí)行乘操作之后把值賦給Rd。Rd = Rm * Rs.
mla指令對(duì)Rd和Rs執(zhí)行乘操作之后并加上Rn后賦值給Rd. Rd = Rm * Rs + Rn。


mull, mlal指令:
語法:umull RdLo, RdHi, Rm, Rs:把Rm和Rs當(dāng)作32位無符號(hào)數(shù)執(zhí)行乘法操作,然后把結(jié)果的低32位賦給RdLo, 高32位賦給RdHi
umlal RdLo, RdHi, Rm, Rs:把Rm和Rs當(dāng)作32位無符號(hào)數(shù)執(zhí)行乘法操作,再加上由RdHi和RdLo組成的64位數(shù),然后把結(jié)果的低32位賦給RdLo, 高32位賦給RdHi
smull RdLo, RdHi, Rm, Rs:把Rm和Rs當(dāng)作32位有符號(hào)數(shù)執(zhí)行乘法操作,然后把結(jié)果的低32位賦給RdLo, 高32位賦給RdHi
smlal RdLo, RdHi, Rm, Rs:把Rm和Rs當(dāng)作32位有符號(hào)數(shù)執(zhí)行乘法操作,再加上由RdHi和RdLo組成的64位數(shù),然后把結(jié)果的低32位賦給RdLo, 高32位賦給RdHi


ldr, str指令:
語法: Rd,

ldr用于從內(nèi)存中加載數(shù)據(jù)到寄存器。
str用于存儲(chǔ)寄存器中的數(shù)據(jù)到內(nèi)存中。

例子:

.LC:
ldr r0, .LC:表示把.LC所處內(nèi)存地址里面的4個(gè)字節(jié)值賦給r0(這種情況需要此命令與標(biāo)簽在同一段內(nèi))
ldr r0, =.LC:表示直接把.LC所處的地址賦給r0
ldr r0, [r1] : 表示把把r1所代表的內(nèi)存地址里面的值賦給r0
ldr r0, [r1, #8] : 表示r1加上8個(gè)字節(jié)代表的內(nèi)存地址里面的值賦給r0
ldr r0, [r1, #8]!: 表示r1加上8個(gè)字節(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指令:
語法: Rn{!}, {^}

Rlist, 表示寄存器列表。比如{r0, r2, r5-r7,r9 }
{!}, 表示執(zhí)行完ldm或stm之后是否對(duì)Rn進(jìn)行回寫。
{^}, 表示恢復(fù)spsr中的值到cpsr。(一般用于返回以前模式)

寄存器列表中的數(shù)據(jù)在內(nèi)存中將被存放的順序?yàn)榈图拇嫫鲗?duì)應(yīng)低內(nèi)存地址的順序存放。
stm操作始終與所指定的棧的方向保持相同,ldm相反。stm就相當(dāng)于壓棧,ldm就相當(dāng)于退棧。

stm表示把寄存器的數(shù)據(jù)存入內(nèi)存
ldm表示把內(nèi)存中的數(shù)據(jù)加載到寄存器上。

例如:
ldmfdsp, {r0,r1,r2} 表示把sp所指的內(nèi)存地址開始的12個(gè)字節(jié)分別賦值給r0,r1,r2。
ldmfdsp!, {r0,r1,r2} 表示把sp所指的內(nèi)存地址開始的12個(gè)字節(jié)分別賦值給r0,r1,r2,之后sp = sp + 12
ldmfd sp!, {r15}^表示把sp棧所指的4個(gè)字節(jié)里面的值賦給r15, 同時(shí)把spsr賦值給cpsr,并且sp += 4

stmfd sp, {r0, r1, r2} 表示把r2,r1,r0按照sp所指地址遞減存儲(chǔ)。也就相當(dāng)于下面3條指令:
str r2, [sp, #-4]
str r1, [sp, #-8]
str r0, [sp, #-12]

stmfd sp!, {r0, r1, r2} 表示把r2,r1,r0按照sp所指地址遞減存儲(chǔ)。并且把sp = sp - 12,也就相當(dāng)于下面4條指令:
str r2, [sp, #-4]
str r1, [sp, #-8]
str r0, [sp, #-12]
sub sp, sp, #12


特殊用法:

stmfd sp!, {r0-r15}^ : 表示把用戶模式下面的r0-r15寄存器存在當(dāng)前模式下面的sp所指向的棧中。
stmfd sp!, {r0-r14}^ : 表示把用戶模式下面的r0-r14寄存器存在當(dāng)前模式下面的sp所指向的棧中。用于進(jìn)程切換的時(shí)候保存用戶模式下面的寄存器。
ldmfd sp!, {r0-r14}^ : 寄存器列表這里面不帶有r15(pc), 表示把當(dāng)前模式下面sp所指的棧中的15個(gè)int拷貝用戶模式下面的r0-r14。這個(gè)用于恢復(fù)進(jìn)程狀態(tài)。

swp指令:
語法: Rd, Rm, [rn]

swp指令執(zhí)行單字節(jié)或單字的內(nèi)存于寄存器的數(shù)據(jù)交換原子操作。把rn所指內(nèi)存里面的值賦值給Rd, 然后把R1存入R2所指的內(nèi)存。經(jīng)常用于內(nèi)核中實(shí)現(xiàn)控制互斥與信號(hào)等功能。

例如:

swp r0, r1,[r2]:表示把r2所指的內(nèi)存地址里面的值賦值給r0, 然后把r1存入r2所指內(nèi)存地址。相當(dāng)于下面2條指令的原子操作。
ldr r0, [r2]
str r1, [r2]



關(guān)鍵詞: ARM常用指

評(píng)論


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

關(guān)閉