久久婷婷香蕉热狠狠综合,精品无码国产自产拍在线观看蜜,寡妇房东在做爰3,中文字幕日本人妻久久久免费,国产成人精品三上悠亚久久

當前位置:首頁 > 嵌入式培訓 > 嵌入式學習 > 講師博文 > ARM指令集如(ru)何應用

ARM指令(ling)集如何應用(yong) 時(shi)間:2018-08-14      來(lai)源:未(wei)知

ARM指(zhi)(zhi)令也稱ARM匯(hui)編(bian)(bian)指(zhi)(zhi)令集,是用來(lai)操作及控制(zhi)ARM處理器(qi)及其相關設備的32bit的匯(hui)編(bian)(bian)指(zhi)(zhi)令,相對于(yu)16bit的thumb指(zhi)(zhi)令集而言功能更(geng)加強(qiang)大(da),包(bao)含指(zhi)(zhi)令與偽指(zhi)(zhi)令。現將常(chang)用指(zhi)(zhi)令歸納(na)匯(hui)總如下(xia):

一、指令、偽指令

指令(ling):是(shi)機器碼的助記符(fu),經(jing)過匯編(bian)器編(bian)譯為機器碼后(hou),可以由CPU執行。

偽指令(ling):用來指導匯編(bian)器編(bian)譯指令(ling),是匯編(bian)器的產(chan)物,終不會生成機器碼。

二、ARM指令的編寫風格

匯(hui)編代(dai)碼大寫:在Windows中的IDE開發環境中一(yi)般都(dou)大寫。

匯編(bian)代(dai)碼小寫(xie):在Linux環境中,好(hao)遵循GNU風格,即指令一般用小寫(xie)。

三、ARM匯編代碼文件后綴的大小寫問題

Windows環境:因為Windows不區(qu)分大(da)小寫(xie),所(suo)以匯編文件后(hou)綴大(da)寫(xie)、小寫(xie)編譯過程沒有區(qu)別,即test.S與(yu)test.s編譯結果一致(zhi)。

Linux環(huan)(huan)境(jing)(jing):Linux環(huan)(huan)境(jing)(jing)是(shi)嚴格(ge)區分大(da)小寫的(de)(de),test.S與test.s會被當成不(bu)同的(de)(de)文件來處理(li)(處理(li)過程(cheng)也不(bu)一(yi)致)。后(hou)綴小寫的(de)(de)test.s文件,在(zai)(zai)編譯階段不(bu)進行預(yu)處理(li)操作(zuo),所(suo)(suo)以(yi)不(bu)能在(zai)(zai)這里面寫預(yu)處理(li)的(de)(de)語句(不(bu)能有宏定義等,不(bu)常用);后(hou)綴大(da)寫的(de)(de)test.S文件,會進行預(yu)處理(li)、匯編等操作(zuo),所(suo)(suo)以(yi)我們可以(yi)在(zai)(zai)這里面加入預(yu)處理(li)的(de)(de)命令(比較常用)。

四、ARM匯編指令的格式

ARM匯編指令(ling)的格式比較固(gu)定、簡(jian)單(dan),即是:“操作碼目標(biao)寄存器,操作數1,操作數2,……操作數n”。

例如將十六(liu)進制數(shu)(shu)(shu)(shu)0xaf放到(dao)寄(ji)存(cun)器r0中(zhong)(zhong)(zhong),我(wo)們(men)用匯編代碼可以這(zhe)樣寫“mov r0,#0xaf”。這(zhe)里的“mov”就(jiu)是(shi)操作碼(指(zhi)令(ling)),實現的功(gong)能是(shi)將“0xaf”這(zhe)個(ge)數(shu)(shu)(shu)(shu)存(cun)放到(dao)寄(ji)存(cun)器中(zhong)(zhong)(zhong)“r0”中(zhong)(zhong)(zhong),“r0”也即(ji)(ji)(ji)(ji)是(shi)目標寄(ji)存(cun)器,“#0xaf”也即(ji)(ji)(ji)(ji)是(shi)操作數(shu)(shu)(shu)(shu)。在這(zhe)里,“#0xaf”表(biao)示(shi)立(li)即(ji)(ji)(ji)(ji)數(shu)(shu)(shu)(shu)(立(li)即(ji)(ji)(ji)(ji)尋(xun)址方式指(zhi)令(ling)中(zhong)(zhong)(zhong)給出(chu)的數(shu)(shu)(shu)(shu)稱為立(li)即(ji)(ji)(ji)(ji)數(shu)(shu)(shu)(shu)立(li)即(ji)(ji)(ji)(ji)數(shu)(shu)(shu)(shu),亦即(ji)(ji)(ji)(ji)是(shi)直接參(can)與運算不(bu)需(xu)處理的數(shu)(shu)(shu)(shu)),立(li)即(ji)(ji)(ji)(ji)數(shu)(shu)(shu)(shu)需(xu)要用“#”來標識(shi)。

五、ARM指令分類

ARM指(zhi)(zhi)令(ling)可以分(fen)為(wei)程(cheng)序狀態寄存器操作(zuo)指(zhi)(zhi)令(ling)、寄存器裝載與(yu)存儲指(zhi)(zhi)令(ling)、算術與(yu)邏輯指(zhi)(zhi)令(ling)、移位指(zhi)(zhi)令(ling)、乘法(fa)指(zhi)(zhi)令(ling)、比較(jiao)指(zhi)(zhi)令(ling)、分(fen)支指(zhi)(zhi)令(ling)、浮點數指(zhi)(zhi)令(ling)、偽指(zhi)(zhi)令(ling)。

1、程序狀態寄存器操作(zuo)指令

程序狀態(tai)寄(ji)存器操(cao)作指令包含msr、mrs兩個指令。

(1)msr實現將通用(yong)寄(ji)存器(qi)(r0-r15)的值復(fu)制(zhi)到狀態(tai)寄(ji)存器(qi)(cpsr及spsr)中,用(yong)于更改處理器(qi)的工作模式及狀態(tai)。例如,

MSR CPSR, R0 ;復制 R0 到 CPSR 中

MSR SPSR, R0 ;復(fu)制 R0 到 SPSR 中

 (2)mrs實現將(jiang)狀態寄存器(qi)(cpsr及spsr)的(de)值復制到通用寄存器(qi)(r0-r15)中(zhong),用于讀取(qu)處理器(qi)的(de)工作(zuo)模式及狀態。例(li)如,

MRS R0, CPSR ; 復(fu)制 CPSR 到 R0 中

MRS R0, SPSR ; 復制 SPSR 到 R0 中

2、寄存器裝載與存儲(chu)指令

常(chang)用寄存器(qi)裝載與存儲指令操作(zuo)指令包含ldr、str、ldm、stm四(si)個指令,其中ldm、stm可以實現多(duo)個數據的傳輸(shu)。

(1)ldr實現(xian)將所(suo)在內存地址的值裝載(zai)到(dao)寄(ji)存器中。

ldr rd, [rbase] ;rbase的值(zhi)存儲到rd寄存器

(2)str實現將寄(ji)存中的值存儲在相(xiang)應內存地址中。

 str rd, [rbase] ;存(cun)儲 rd 到 rbase 所(suo)包含的有效地址

(3)ldm實(shi)現將內存的值存儲(chu)在相應寄存器地址中。常(chang)用于數據出棧。

ldmfd sp!, {r0-r3} ;將內存的數據出棧到r0-r3

(4)stm實現將寄存(cun)中的值存(cun)儲在相應內存(cun)地址中。常用(yong)于數據入棧。

stmfd sp, {r0-r3} ;將寄存器r0-r3壓棧

3、算術與邏輯(ji)指令

常用(yong)算(suan)術與邏(luo)輯(ji)指令(ling)包含and、orr、eor三(san)個(ge)邏(luo)輯(ji)指令(ling)和adc、add、bic、mov、mvn、rsb、sub六個(ge)算(suan)術指令(ling),共計九個(ge)指令(ling)。

(1)and實現邏輯與(yu),相當于c語言中(zhong)的位(wei)與(yu)。

and r0, r1, #0x01 ; r0=r1 & 0x01

(2)orr實(shi)現(xian)邏輯(ji)或(huo),相當(dang)于c語言中的位或(huo)。

orr r0, r1, #0x01 ; r0=r1 | 0x01

(3)eor實現異或,相當于c語言中(zhong)的異或。

eor r0, r1, #0x01 ; r0=r1 ^ 0x01

(4)bic實現清(qing)零操作。

bic r0, r0, #0x0f ; r0 = r0 & ~(0x0f)技術將低4bit清(qing)零

(5)mov實現數(shu)(shu)據的搬移,相當于(yu)c語言中的賦(fu)值(如果后面是立即(ji)(ji)數(shu)(shu),這個立即(ji)(ji)數(shu)(shu)的范圍(wei)一(yi)般是0~255(8bit))。

mov r0,#0x01 ; r0 = 0x01

mov r0,r1 ; r0 = r1

(6)mvn實現數據的(de)取反并(bing)搬移(yi),相當(dang)于c語言的(de)取反在賦(fu)值。

mvn r0,#1 ; r0 = (~1) = -2

mvn r0,r1 ; r0 = (~r1) = -(r1 + 1)

(7)rsb實現(xian)反向減法。

rsb r0, r1, #20 ; r0 = 20 - r1

rsb r0, r1, r2 ; r0 = r2 - r1

(8)add實(shi)現算(suan)術(shu)加法。

add r0, r1, #0x01 ; r0 = r1 + 0x01

(9)sub實現算術減法(fa)。

sub r0, r1, #0x01 ; r0=r1 - 0x01

4、移位指令

移位指(zhi)令(ling)(ling)包含lsl、asl兩個左(zuo)移指(zhi)令(ling)(ling)和lsr、asr、ror、rrx四個右移指(zhi)令(ling)(ling),共計六(liu)個指(zhi)令(ling)(ling)。

(1)lsl實(shi)現邏(luo)輯(ji)左移,與(yu)asl作用等同。

mov r1, #0x21 ;將立即數0x21放(fang)到r1

mov r0, r1, lsl#3 ;將(jiang)r1左移3位,然后(hou)放入r0中

(2)asl實現(xian)算術(shu)左移,與(yu)lsl作用等同。

mov r1, #0x21 ;將立(li)即數0x21放到r1

mov r0, r1, asl#3 ;將r1左移3位(wei),然(ran)后放入(ru)r0中

(3)lsr實現邏輯右移。

mov r1, #0x21 ;將(jiang)立即(ji)數(shu)0x21放到r1

mov r0, r1, lsr#3 ;將r1右移3位,然后放入r0中

(4)asr實現(xian)算術右移。

mov r1, #0x21 ;將(jiang)立即數0x21放(fang)到r1

mov r0, r1, asr#3 ;將r1右移3位,然后(hou)放入r0中

(5)ror實現循環右移。

mov r1, #0x21 ;將立即數0x21放到r1

mov r0, r1, ror#3 ;將r1右移(yi)3位(wei),移(yi)出的位(wei)放(fang)依次放(fang)到高(gao)位(wei),然后放(fang)到r0中

(6)rrx實現帶擴展的循環右移

mov r1, #0x21 ;將立(li)即數0x21放到(dao)r1

mov r0, r1, rrx#3 ;將r1右移3位(wei)(wei),移出的位(wei)(wei)放(fang)(fang)(fang)依次放(fang)(fang)(fang)到高(gao)位(wei)(wei)(借一位(wei)(wei)構成33bit),然后放(fang)(fang)(fang)到r0中

5、乘法指令

乘法(fa)指(zhi)令操作指(zhi)令包(bao)含mla、mul兩個指(zhi)令。

(1)mla是三目乘法(fa)指令(有三個(ge)操作數(shu))。例如:

mla r0, r1,r2,r3 ;r0 = (r1 * r2) + r3

(2)mul是兩目(mu)乘法指令(ling)(有兩個(ge)操(cao)作數)。例如:

mul r0, r1, r2 ;r0 = r1 * r2

6、比較指令

常用比(bi)較(jiao)指令包含cmp、cmn兩個指令。

(1)cmp實(shi)現比(bi)較功能(neng),例(li)如,cmp r0, r1 ;r0-r1

(2)cmn實現取負的值的比較功能,例(li)如,cmn r0, r1 ;r0-(-r1)

7、分支(zhi)指(zhi)令(ling)

分(fen)支指令(ling)包含b、bl兩個指令(ling)。

(1)b為(wei)不帶連接的(de)分(fen)支指令(ling),當程序(xu)(xu)從當前(qian)位置(zhi)調到(dao)分(fen)支程序(xu)(xu)中執行,將無法再返(fan)回到(dao)當前(qian)位置(zhi)的(de)下一條指令(ling)處。例如:

.start

.loop

mov r0,#0x01 ;將0x01加(jia)載到r0寄存(cun)器

…………

b loop ; ;調到loop

mov r1,#0x01 ;將(jiang)0x01加(jia)載(zai)到r1寄存(cun)器

程序(xu)將(jiang)一直在loop這里循環(相當于(yu)while循環),“mov r1,#0x01”永遠得(de)不到執行(xing)。

(2)bl為帶連接的分(fen)(fen)支指令(branch and link),跳轉前把(ba)返(fan)回地址(zhi)放入lr中,以便用(yong)于函數調當(dang)程(cheng)序(xu)從當(dang)前位置調到(dao)分(fen)(fen)支程(cheng)序(xu)中執(zhi)行,執(zhi)行完分(fen)(fen)支程(cheng)序(xu)將再(zai)返(fan)回到(dao)當(dang)前位置的下一條指令處繼續執(zhi)行。例如:

.start

.loop

mov r0,#0x01 ;將0x01加載到r0寄存器

…………

bl loop ;調到loop

mov r1,#0x01 ;將0x01加載到r1寄存器

程序執行完loop后調到下一(yi)行的(de)“mov r1,#0x01”處(chu)執行。

8、浮點數指令(ling)

浮點數指(zhi)令(ling)很多(duo),常用指(zhi)令(ling)有abs、cmf、dvf、mvf、muf、ldf、suf、adf幾(ji)個(ge)指(zhi)令(ling),用于處理浮點數的加載、加、減、乘、除。

9、偽指令

偽指令(ling)(ling)操作(zuo)指令(ling)(ling)包(bao)含adr、adrl、align、dcx、equx、opt六個指令(ling)(ling),用(yong)于描述指定匯(hui)編代碼的對(dui)齊方(fang)式(shi)、宏定義等。

六、常用GNU偽指令

global _start @ 給_start外部(bu)鏈接屬性(xing)

.section .text @ 指定當前段(duan)為代碼段(duan)

.ascii .byte .short .long .word

.quad .float .string @ 定義數據

.align 4 @ 以4字節對齊

.balignl 16 0xabcdefgh @ 16字節(jie)對齊(qi)填充

.equ @ 類似于C中宏定義

.end @標識文件結束

.include @ 頭文件包含

.arm / .code32 @聲(sheng)明以下為arm指令

.thumb / .code16 @聲明以(yi)下為thubm指令

ldr 大范圍的地址加載(zai)指(zhi)令

adr 小范圍的地(di)址加載指令

adrl 中等(deng)范圍的地址加載指(zhi)令

nop 空操作

七、常用的8種尋址方式的指令實現

1、寄存器(qi)尋址

寄存器(qi)尋址(zhi)就是利用寄存器(qi)中(zhong)的數值(zhi)作(zuo)為操作(zuo)數,是一種執行(xing)效(xiao)率(lv)較高的尋址(zhi)方(fang)式。例如(ru):

mov r1, r2 ;r1 = r2

2、立即(立即數)尋址(zhi)

立(li)即(ji)尋址(zhi)(zhi)(zhi)(zhi)也叫立(li)即(ji)數尋址(zhi)(zhi)(zhi)(zhi),這是一種特殊的尋址(zhi)(zhi)(zhi)(zhi)方式(shi),操(cao)作(zuo)數本身就是在指(zhi)令中(zhong)給出(chu),只(zhi)要取出(chu)指(zhi)令也就渠道了操(cao)作(zuo)數。這個操(cao)作(zuo)數被稱為立(li)即(ji)數,對應的尋址(zhi)(zhi)(zhi)(zhi)方式(shi)也叫作(zuo)立(li)即(ji)尋址(zhi)(zhi)(zhi)(zhi)。例如:

mov r0, #0xff00 ; r0 = 0xff00

3、寄存器移(yi)位尋(xun)址(zhi)

將寄(ji)存器(qi)(該(gai)寄(ji)存器(qi)一(yi)般稱(cheng)作(zuo)基(ji)址(zhi)寄(ji)存器(qi))的(de)內容(rong)與指令中給出的(de)地(di)址(zhi)偏(pian)移量相加,從而(er)得到一(yi)個操作(zuo)數的(de)有(you)效地(di)址(zhi)。例如(ru):

mov r0, r1, lsl #3 ; r0 = r1 << 3

4、寄(ji)存器間接尋址(zhi)

寄存器間接尋址(zhi)就是以寄存器中(zhong)的值作(zuo)為操作(zuo)數的地址(zhi),而操作(zuo)數本身存放在存儲器中(zhong)。例(li)如:

ldr r0, [r1] ;將內存(cun)地址(zhi)存(cun)在r1這個寄(ji)存(cun)器中(zhong)的內存(cun)地址(zhi)里(li)的值給r0

5、基址尋址

 基(ji)(ji)址尋址就是將(jiang)基(ji)(ji)址寄(ji)存(cun)器的(de)內容與指(zhi)令中(zhong)給出的(de)偏移量相(xiang)加,形成操(cao)作數的(de)有效地址。常用于查表、數組操(cao)作、功能部件寄(ji)存(cun)器訪問等。例(li)如:

LDRR2,[R3,#0x0C];讀(du)取(qu)R3+0x0C地址上(shang)的(de)內(nei)容,放入R2

6、塊拷貝尋址

 多寄存器(qi)傳送指令用(yong)于將一塊(kuai)數據從存儲器(qi)的某一位(wei)置(zhi)拷貝到另(ling)一位(wei)置(zhi)。例如,

STMIAR0!,{R1-R7} ;將(jiang)R1~R7的數據保存(cun)到存(cun)儲器中

7、多寄存器尋址

利用(yong)(yong)一(yi)條指令可以完(wan)成(cheng)多(duo)個(ge)寄存器(qi)值(zhi)的傳送。這(zhe)種尋址方式可以用(yong)(yong)一(yi)條指令完(wan)成(cheng)傳送多(duo)16個(ge)通用(yong)(yong)寄存器(qi)的值(zhi)

ldmia r1!, {r2-r7, r12} ;一次訪(fang)問多個寄(ji)存器

8、堆棧尋址

堆(dui)棧(zhan)(zhan)是一種數據結構,按(an)先進后出的(de)方式工作(zuo),使用一個稱作(zuo)堆(dui)棧(zhan)(zhan)指(zhi)針的(de)專用寄存器(qi)指(zhi)示當(dang)前的(de)操(cao)作(zuo)位置,堆(dui)棧(zhan)(zhan)指(zhi)針總是指(zhi)向棧(zhan)(zhan)頂。例子,

stmfd sp!, {r2-r7, lr}

八、常用指令后綴

同一(yi)指令經(jing)常附帶不同后(hou)(hou)綴,變成不同的指令。經(jing)常使用(yong)的后(hou)(hou)綴有:

1、B(byte)功(gong)能不(bu)變(bian),操(cao)作長度變(bian)為8位(wei)

2、H(half word)功(gong)能不變(bian)(bian),長(chang)度變(bian)(bian)為16位

3、S(signed)功能(neng)不變,操(cao)作(zuo)數(shu)變為有符號

4、條件(jian)執行后綴(zhui)

5、“!”與(yu)“^”的作用

例如ldr可以加“b”、“h”、“s”變成 ldrb、ldrh、ldrsb、ldrsh用于表示加載8bit數據、16bit數據、有符號8bit數據、有符號16bit數據。

條(tiao)件執行(xing)后(hou)綴(zhui),可以參看下表例(li)。特點是(shi)條(tiao)件后(hou)綴(zhui)是(shi)否成立取決(jue)于當(dang)前代(dai)碼(ma)的(de)前面的(de)代(dai)碼(ma),只影響當(dang)前代(dai)碼(ma)的(de)執行(xing)。

ARM指令集

感嘆號的(de)作用就(jiu)是r0的(de)值在(zai)ldm過程中(zhong)發生的(de)增(zeng)加或者減少后寫回到r0去,也就(jiu)是說ldm時會(hui)改變r0的(de)值。例(li)如,

ldmia r0, {r2 - r3} ;不會改變r0的值

ldmia r0!, {r2 - r3} ;會改變r0的值

^的作用是在目標(biao)寄(ji)存(cun)器中有(you)pc時(shi),會同時(shi)將spsr寫入到cpsr,一(yi)般用于從(cong)異常模式返回。

ldmfd sp!, {r0 - r6, pc} ;spsr不會寫入到cpsr

ldmfd sp!, {r0 - r6, pc}^ ;spsr寫入到(dao)cpsr

九、ARM指令應用舉例

這里就ARM應用(yong)舉一(yi)個例子,使用(yong)ARM指(zhi)令(ling)操作簡單(dan)的(de)硬件(點亮LED燈)。FS210開發板LED燈如下圖所示,

ARM指令集

要想控制這(zhe)些器件,我們(men)需(xu)要查看其(qi)對應的原理(li)(li)圖。LED原理(li)(li)圖如(ru)下

ARM指令集

從原理(li)圖上可知(zhi),要想點亮(liang)兩顆led燈,只需給GPC0_3及GPC0_4高電(dian)平即可。

ARM指令集

打(da)開S5PV210用戶手冊,找到GPIO章節的數據寄存(cun)(cun)器與控制寄存(cun)(cun)器的描述。結合(he)GPIO寄存(cun)(cun)器的描述編寫(xie)匯(hui)編程序。

#define GPC0_CON 0XE0200060 ;定義GPC0控制寄存器地址

#define GPC0_DAT 0XE0200064 ;定義GPC0數據寄存器地址(zhi)

ldr r0,=GPC0_CON ;將GPC0_CON加載到r0

ldr r1,=0x11000 ;將0x11000加(jia)載到r1

str r1,[r0] ;將r1的值加載到r0寄存器

ldr r0,=GPC0_DAT ;將(jiang)GPC0_DAT加(jia)載到r0

mov r1,#0x18 ;將立即數0x18加(jia)載到r1

str r1,[r0] ;將(jiang)r1的值加載到r0寄存器

stop:

b stop ;死循環(相當于while(1))

交叉(cha)編譯并下載到FS210開發板上運行,LED燈(deng)被點亮。

ARM指令集

上一篇:TFT-LCD常用接口分類

下一篇:嵌入式硬件開發怎么學

熱(re)點文(wen)章(zhang)推薦(jian)
華(hua)清學員(yuan)就業榜(bang)單
高薪學(xue)員經(jing)驗分享
熱(re)點新聞(wen)推薦(jian)
前臺專線:010-82525158 企業培訓洽(qia)談(tan)專線(xian):010-82525379 院校合作洽(qia)談專(zhuan)線:010-82525379 Copyright © 2004-2022 北京華清遠見科技集團有限公司 版權所有 ,,京公海網安備11010802025203號

回到頂部