国产成人精品三级麻豆,色综合天天综合高清网,亚洲精品夜夜夜,国产成人综合在线女婷五月99播放,色婷婷色综合激情国产日韩

當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 入門指導(dǎo) > arm程序匯編指令總結(jié),讓你更高效的學(xué)習(xí)

arm程序匯編指令總結(jié),讓你更高效的學(xué)習(xí) 時(shí)間:2018-07-16      來源:未知

現(xiàn)在學(xué)嵌入式的人也是越來越多了,那當(dāng)然arm程序也是必須要學(xué)的,在這里有很多人對(duì)arm程序匯編指令都或多或少的不了解,可以說不熟悉,今天就以arm程序來看,讓你對(duì)arm程序匯編指令有更深入的學(xué)習(xí)。

首先我們要知道arm匯編程序的特點(diǎn):

l 所有運(yùn)算處理都是發(fā)生通用寄存器(一般是R0~R14)的之中.所有存儲(chǔ)器空間(如C語言變量的本質(zhì)就是一個(gè)存儲(chǔ)器空間上的幾個(gè)BYTE).的值的處理,都是要傳送到通用寄存器來完成.因此代碼中大量看到LDR,STR指令來傳送值.

l ARM匯編語句中.當(dāng)前語句很多時(shí)候要隱含的使用上一句的執(zhí)行結(jié)果.而且上一句的執(zhí)行結(jié)果,是放在CPSR寄存器里,(比如說進(jìn)位,為0,為負(fù)…)

CMP R0,R1

BNE NoMatch

比如上一句,BNE隱含的使用的上一句CMP執(zhí)行結(jié)果.NE后綴表示使用Z標(biāo)志位.兩句合起來的意思就是,如果R0,R1的值不相等,就跳轉(zhuǎn)到NoMatch處執(zhí)行.

注意,PC=R15,CPSR=R16,

arm程序

ARM常用指令,偽指令

對(duì)于arm指令你要知道一個(gè)問題就是arm偽指令

ARM偽指令不是必須的,但是一個(gè)完整沒有偽指令幾乎很難寫出來.

n 比如一個(gè)程序至少包含READONLY AREA和ENTRY,否則CPU都無法知道從哪里開始運(yùn)行

l ARM的屬于RISC,指令并不多,但是可以帶后綴表示擴(kuò)展出不同用法,這里與X86匯編完全不同風(fēng)格

n 如BNE實(shí)際上是B指令的變種,本質(zhì)還同一類指令.只是多一個(gè)對(duì)CPSR的Z標(biāo)志位的判斷。

首先我們要從ARM程序常用指令來了解,這些都是你要學(xué)習(xí)的哦,雖然不是很詳細(xì)但是對(duì)于學(xué)習(xí)ARM程序來說這些就夠了。

l B,BL

l MOV,MVN

l LDR,STR

l ADD,SUB,ADC,SBC,MUL

l AND,ORR,XOR,TST,BIC

l CMP

l LDM/STM

l nop

1. 傳輸數(shù)據(jù)指令MOV,MVN

n MOV(MOVE)指令可完成從另一個(gè)寄存器、被移位的寄存器或?qū)⒁粋(gè)立即數(shù)加載到目的寄存器

MOV R0,R1 ; 把R1的值傳到R0

MOV R3,#3 ;把常數(shù)3傳給R3,MOV中用#表示常數(shù),這個(gè)值不能超過

n MVN( MOVE Negative)取反后再傳值,比MOV多了一步取反

MVN R0, #0 ;把0取反(即-1)傳給R0

MVN R1,R2 ;把R2的值取反傳給R1

2. 跳轉(zhuǎn)語句 B,BL

程序流程的跳轉(zhuǎn),在 ARM 程序中有兩種方法可以實(shí)現(xiàn)程序流程的跳轉(zhuǎn)指令用于實(shí)現(xiàn)

l 使用專門的跳轉(zhuǎn)指令 B

l 直接向程序計(jì)數(shù)器PC 寫入跳轉(zhuǎn)地址值

n 這是幾乎是任何一種CPU必備的機(jī)器,PC表示CPU當(dāng)前執(zhí)行語句位置,改變PC的值,相當(dāng)于實(shí)現(xiàn)程序跳轉(zhuǎn)

n 如實(shí)現(xiàn)類似C語言的Return 語句,就是用MOV PC,LR

n 這里可以在任意4G的空間進(jìn)行跳轉(zhuǎn)

B指令(Branch)表示無條件跳轉(zhuǎn).

B main ;跳轉(zhuǎn)到標(biāo)號(hào)為main地代碼處

BL指令(Branch with Link)表示帶返回值的跳轉(zhuǎn).

BL比B多做一步,在跳轉(zhuǎn)前,BL會(huì)把當(dāng)前位置保存在R14(即LR寄存器),當(dāng)跳轉(zhuǎn)代碼結(jié)束后,用MOV PC,LR指令跳回來,這實(shí)際上就是C語言執(zhí)行函數(shù)的用法,

匯編里調(diào)子程序都用BL,執(zhí)行完子函數(shù)后,可以用MOV PC,LR跳回來.

BL delay ;執(zhí)行子函數(shù)或代碼段delay ,delay可以為C函數(shù).

與MOV PC,XXX能在4G空間跳轉(zhuǎn)不同,B語句只能32M空間跳轉(zhuǎn),(因?yàn)槠屏渴且粋(gè)有符號(hào)26bit的數(shù)值=32M)

3. 算術(shù)運(yùn)算指令,ADD/ADC,SUB/SBC ,MUL

n ADD加法指令

ADD R0,R1,R2; R0=R1+R2

ADD R0,R1,#3 ;R0=R1+3

n ADC帶進(jìn)位加法指令,即除了加兩個(gè)數(shù)以外,還要把CPSR的C值也要帶進(jìn)來

u 通常用于大數(shù)(超過32Bit整數(shù))相加,這時(shí)單用ADD不能處理,必須折成兩步,其中一步用ADC.

u 以下是做64Bit的加法

ADDS R0,R1,R2; R0=R1+R2,ADDS中S表示把進(jìn)位結(jié)果寫入CPSR

ADC R5,R3,R4 ;R5=R3+R4+C

n SUB減法指令

SUB R0,R1,R2; R0=R1-R2

SUB R0,R1,#3 ;R0=R1-3

n SBC帶進(jìn)位減法指令,即除了加兩個(gè)數(shù)以外,還要把CPSR的C值也要帶進(jìn)來,類似ADC

u 以下是做64Bit的減法

SUBS R0,R1,R2; R0=R1-R2,SUBS中S表示把進(jìn)位結(jié)果寫入CPSR

SBC R5,R3,R4 ;R5=R3-R4-C

n MUL 乘法指令

MUL R0,R1,R2; R0=R1*R2

MUL R0,R1,#3 ;R0=R1*3

4. 加載/存儲(chǔ)指令,LDR,STR

n LDR,STR是用于寄存器和外部存儲(chǔ)器交換數(shù)據(jù)指令,注意與MOV的區(qū)別,后面只在寄存器或常數(shù)交換.

u LDR/STR可以采用多種尋址方式,以下只舉出使用頻率最高幾種用法

n LDR(load)用于把一個(gè)32Bit的WORD數(shù)據(jù)從外部存儲(chǔ)空間裝入到寄存器中

LDR R0,[R1]; R1的值當(dāng)成地址,再從這個(gè)地址裝入數(shù)據(jù)到R0 (R0=*R1)

LDR R1,=0x30008000 ; 把地址0x30008000的值裝入到R1中,LDR中用常數(shù)要用=打頭.(注意跟MOV的區(qū)別,MOV是#)

ldr r0, =(0<<13)|(0<<12)|(0<<10)|(0<<9)|(0<<8)|(1<<6)|(1<<5)|(1<<4)|(1<<1)|(1<<0)

用位與的方法賦值

n STR(Store) 用于把一個(gè)寄存器的值存入外部存儲(chǔ)空間,是LDR的逆操作.

STR R0,[R1] ; 把R0的值,存入到R1對(duì)應(yīng)地址空間上(*R1 = R0)

STR R0,=0x30008000 ;把R0中值存入到地址0x30008000

S2C2440的中CPU內(nèi)核以外的模塊的控制寄存器空間也是屬于外部空間,所以也得用如下指令LDR R0,=GPFDAT

5. 比較指令 CMP

n CMP比較兩個(gè)操作數(shù),并把結(jié)果存入CPSR供下一句語句使用

CMP R0,R1; 比較R0,R1

6. 位操作指令 AND,ORR, TST,BIC

n AND位與指令

AND R0,R1,R2; R0=R1 & R2

AND R0,R1,#0xFF ;R0=R1 & 0xFF

n ORR位或指令

ORR R0,R1,R2; R0=R1 | R2

ORR R0,R1,#0xFF ;R0=R1 | 0xFF

n TST測試某一位是否為1,并把結(jié)果寫入CPSR,供下一句使用

TST R1,#0xffe; 等同于if(R1 & 0xffe)

TST R1,#%1;測試最低位是否為1,%表示二進(jìn)制

n BIC清位操作

BIC R0,R0,#0xF ; 等同于 R0 &=~(0xF)

BIC R0,R0,#%1011 ; 該指令清除 R0 中的位 0 1 3,其余的位保持; %表示是二進(jìn)制,0x表示十六進(jìn)制

7. 多寄存器語句傳輸指令,LDM,STM

類似于一次傳一個(gè)BUFFER到寄存器當(dāng)中,或反過來.后面一般要接一個(gè)地址改變方法

n LDM 從BUFFER傳數(shù)據(jù)多個(gè)寄存器傳輸數(shù)據(jù)到

LDMIA R0! ,{R3-R9} ;加R0指向的地址上連續(xù)空間的數(shù)據(jù),保存到R3-R9當(dāng)中,!表示R0值更新,IA后綴表示按WORD遞增

LDMFD SP!,{R0-R7,PC}^;恢復(fù)現(xiàn)場,異常處理返回,^表示不允許在用戶模式下使用。

n STM 從寄存器列表向存儲(chǔ)空間傳值。

STMIA R1!,{R3-R9} ;將R3-R9的數(shù)據(jù)存儲(chǔ)到R1指向的地址上,R1值更新。

STMFD SP!,{R0-R7,LR}; 現(xiàn)場保存,將R0~R7,LR入棧

stmfd sp!,{r8-r9} ,把SP寄存器對(duì)慶的地址的值存到R8,R9當(dāng)中.!表示最后的值寫入SP中。Fd表示

8. ARM指令的變形

大部分指令后位可以接 與S兩個(gè)特殊位來表示,對(duì)CPSR特殊的一些判斷

S,表示當(dāng)前指令執(zhí)行后把結(jié)果改寫CPSR

subs,Adds

取決于具體條件,只有CPSR滿足指定條件時(shí)才指這一指令

BEQ 實(shí)際上B+ EQ的條件執(zhí)行.

addne 表示ADD +NE 才開始加.

9. ADS ARM的偽指令

類似于C語言的宏,由匯編程序預(yù)處理.

l 符號(hào)定義指令

全局變量定義 GBLA ,GBLL,GBLS

局域變量定義 LCLA,LCLL,LCLS

變量賦值SETA,SETL,SETS

其中上述偽指令中,最后面的A表示給一個(gè)算術(shù)變量賦值,L表示用于給一個(gè)邏輯變量賦值,s表示給一個(gè)字符串賦值

GBLL codedbg; 聲明一個(gè)全局的邏輯變量

Codebg SETL {TRUE} ; 設(shè)置變量為{TRUE}

LCLA bitno; 聲明一個(gè)算術(shù)變量

Bitno SETA 8 ;設(shè)變量值為8

l 數(shù)據(jù)定義偽指令

n SPACE 定義一個(gè)內(nèi)存空間,并用0初始化

{label } SPACE expr

DataBuf SPACE 100 ;定義100字節(jié)長空間, unsigned char DataBuf[100];

n DCB 定義一個(gè)連續(xù)字節(jié)內(nèi)存空間,用偽指令的表達(dá)式expr來初始化.一般可以用定義數(shù)據(jù)表格,或文字字符串.(這時(shí)等同于SETS),用于初始二進(jìn)制BUFFER

{label} DCB expr{,expr …}

Dest DCB -120,20,36,55 ;等同于 unsigned char Dest[]={-120,20,36,55};

n DCU定義的一段字的內(nèi)存空間(DCB是字節(jié)),并用后面表達(dá)式初始化

_RESET DCU Reset ; 等同于 DWORD _RESET[]={Reset};

n MAP定一個(gè)結(jié)構(gòu)化內(nèi)存,相當(dāng)于定義一個(gè)C結(jié)構(gòu)

n FILED 定義一個(gè)結(jié)構(gòu)化內(nèi)存的成員

MAP 0x00,R9 ; 定義內(nèi)存表,地址為R9

Timer FIELD 4 ; 定義數(shù)據(jù)域Timer,長為4字

Attrib FIELD 4 ; 定義數(shù)據(jù)域Attrib,長為4字

String FILED 100 ; 定義數(shù)據(jù)域String ,長為100字

相當(dāng)于C語言的定義:

struct {

DWORD Timer ;

DWORD Attrib ;

Char String[100];

} R9;

10. ARM指令的尋址方式

尋址方式是根據(jù)指令中給出的地址碼來定位真實(shí)的地址,ARM中有9種尋址方法

l 寄存器尋址

直接用寄存器編號(hào)來尋址,最為常用

MOV R1,R2 ;R2->R1

l 立即數(shù)尋址

即指令中的地址碼是操作數(shù)本身,可以立即取出使用,立即數(shù)前帶一個(gè)#表示,否則表示一個(gè)地址

SUBS R0,R0,#1 ;R0 -1 ->R0

注意與SUBS R0,R0,1區(qū)別

l 寄存器偏移尋址

這是ARM特有的尋址模式,當(dāng)?shù)?操作數(shù)是寄存器,在執(zhí)行操作之前,可以做一次移位操作

MOV R0,R2,LSL #3 ;R2的邏輯左移3位,結(jié)果放入R0,即R0=R2*8

ANDS R1,R1,R2,LSL R3;RS的值左移R3位,然后和R1相與操作,結(jié)果放入R1

移位操作有LSL (邏輯左移),LSR(邏輯右移) ,ASR(算術(shù)右移),ROR(循環(huán)右移)RRX帶擴(kuò)展的循環(huán)右移

l 寄存器間接尋址

即寄存器中值是一個(gè)地址,用[]來取出定位到地址當(dāng)中

LDR R2,[R0] ;把R0的值當(dāng)成地址,取出相應(yīng)值,賦給R2

l 基址尋址

把寄存器的地址值加上一個(gè)偏移量

LDR R2,[R3,#0x0F]; R3中的值加上0x0F,從這個(gè)地址取出值賦給R@

l 相對(duì)尋址

基址尋址的變形,由PC寄存器提供基準(zhǔn)地址,指令中地址段作為偏移量.兩者相加即是有效地址,以下是BL采用相對(duì)尋址

BL NEXT

NEXT

MOV PC,LR ;從子程序返回

11. 雜項(xiàng)的偽指令

n 字節(jié)對(duì)齊 ALIGN

ALIGN; 聲明4字節(jié)對(duì)齊

n 定義一個(gè)數(shù)字常量定義 EQU

NAME EQU expr {type}

PLLCON EQU 0xE01FC080;定義PLLCON,類似于C的宏或C++的常量

n 包含文件 GET和INCLUDE

INCLUDE lpc2106.inc

n NOP 空指令

在匯編時(shí)會(huì)被ARM的空操作代替,比如MOV R0,R0,一般用于延時(shí)與占位。

n 聲明一個(gè)外部符符號(hào) IMPORT,EXTERN

IMPORT,EXTERN 向外部導(dǎo)入一個(gè)符號(hào),一般是外部程序全局變量

n 條件編譯:[]。類似于C的#ifdef 之類定義。

格式 :[ 條件表達(dá)式

滿足條件分支

|

不滿足條件分支

]

示例1:

[ ENTRY_BUS_WIDTH=32 ;類似#if ENTRY_BUS_WIDTH=32

b ChangeBigEndian ;DCD 0xea000007

] ; 類似#endif

示例2: [ CLKDIV_VAL>1 ; 類似#if CLKDIV_VAL>1

bl MMU_SetAsyncBusMode

|;類似#else

bl MMU_SetFastBusMode ; default value.

]; 類似#endif

示例3 [ THUMBCODE 類似#ifdef THUMBCODE

bx lr

| ;類似#else

mov pc,lr

] ;類似#endif

n 段定義 AREA

n 指令集定義 CODE16和CODE32

指示是Thumb 指令集(壓縮指令集,每個(gè)指令16位)。還是普通32位指令集

n 匯編結(jié)束:END

n 程序入口ENTRY

一直都在說arm程序,那這個(gè)arm程序,你又了解多少呢,在這里在附加arm程序的結(jié)構(gòu),讓你一次性吃個(gè)飽,一個(gè)簡單的arm程序結(jié)構(gòu)一般包括:ARM匯編程序結(jié)構(gòu),ARM 匯編語句格式, 匯編程序的段定義,對(duì)于這些知識(shí)點(diǎn),相信下面這些就夠你學(xué)會(huì)了。

ARM匯編程序結(jié)構(gòu)

源代碼由文本文件組成.按照匯編的編譯器不同,分為兩大量,一類是ADS的匯編程序,一類是GNU匯編格式,兩者在指令集是完成一樣,但是在偽指令.程序結(jié)構(gòu)等方法各不同相同.本節(jié)主要是講解ADS匯編格式.

ADS匯編程序,主要包含如下幾類程序

n 匯編源程序,后綴名是.S

n 匯編包含文件,后綴名是.inc

n 如果是與C混和編程..C,.h也能識(shí)別

匯編程序的段定義

任何一個(gè)程序都要分段,C語言一般由編譯器自動(dòng)分段,(分成.Text,.Data段之類),但在匯編程序這樣的底層程序中,由開發(fā)者自行分段. 它包含如下段

l 至少一個(gè)代碼段,并且代碼段是只讀的,對(duì)應(yīng)(.Text)

l 數(shù)據(jù)段可以沒有,也可以有多個(gè).

l 每一個(gè)段用END結(jié)束

AREA 定義一個(gè)段

AREA 段名 屬性1, 屬性2,

例子:AREA Init,CODE,READONLY

l ENTRY 指明一個(gè)段的入口

l END結(jié)束一個(gè)段

ABC EQU 0x12

AREA Example,CODE,READONLY

ENTRY

START MOV R7,#10

MOV R6,#5

ADD R6,R6,R7

B

END

ADS ARM匯編程序格式要求

1. 所有標(biāo)號(hào)要頂格寫.

2. 所有指令不能頂格寫,一般插入Tab鍵在行首

3. ADS ARM中,是大小寫敏感的.建議標(biāo)號(hào),指令,偽指令,寄存器名全部為大寫

4. 注釋采用;打頭

5. 每個(gè)程序至少有一個(gè)AREA在代碼里(READONLY)

6. 每個(gè)段都要用END結(jié)束(不能頂格)

ARM 匯編語句格式

[標(biāo)號(hào)] <指令|條件|S> <操作數(shù)> [;注釋]

l 所有標(biāo)號(hào)頂格寫,而指令和偽指令不能頂格寫

l 標(biāo)識(shí)符(標(biāo)號(hào),指令)大小寫敏感,所以要在標(biāo)號(hào)和指令時(shí)書寫一致,一般偽指令,指令,寄存器名可以全部為大寫

l 注釋以;開頭,可以頂格寫

l 可以使用\來分行寫太長語句

l 變量,常量的定義必須在一行頂格寫

常量的書寫

l 數(shù)字常量

在程序中直接寫數(shù)字 ,十進(jìn)制 12,256,十六進(jìn)制 0x1228,

l 字符常量

類似于C的定義,用SETS來定義字符常量

HELLO SETS “hello,the world!”

l 邏輯常量

邏輯真為{TRUE},邏輯假為{FLASE}

Testno SETS {TURE}

最常見幾個(gè)偽指令 AREA,EQU,DCB,END ,ENTRY,EXPORT,GOBEL,IMPORT。

就先說到這里了,對(duì)于這些arm程序匯編指令,你是否都掌握好了呢,學(xué)習(xí)arm程序這些是離不開的,需要有邊學(xué)邊記,邊學(xué)邊實(shí)踐,這樣才會(huì)對(duì)arm程序匯編指令都了如指掌。

上一篇:物聯(lián)網(wǎng)倉儲(chǔ)項(xiàng)目學(xué)習(xí)遇到的困難【學(xué)員筆記】

下一篇:嵌入式題庫最全的,去公司面試都會(huì)出現(xiàn)

熱點(diǎn)文章推薦
華清學(xué)員就業(yè)榜單
高薪學(xué)員經(jīng)驗(yàn)分享
熱點(diǎn)新聞推薦
前臺(tái)專線:010-82525158 企業(yè)培訓(xùn)洽談專線:010-82525379 院校合作洽談專線:010-82525379 Copyright © 2004-2022 北京華清遠(yuǎn)見科技集團(tuán)有限公司 版權(quán)所有 ,京ICP備16055225號(hào)-5,京公海網(wǎng)安備11010802025203號(hào)

回到頂部