新聞中心

ARM指令集詳解2

作者: 時(shí)間:2016-11-20 來源:網(wǎng)絡(luò) 收藏
加載和存儲(chǔ)指令

ARM微處理器支持加載/存儲(chǔ)指令用于在寄存器和存儲(chǔ)器之間傳送數(shù)據(jù),加載指令用于將存儲(chǔ)器中的數(shù)據(jù)傳送到寄存器,存儲(chǔ)指令則完成相反的操作。

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

LDR{條件} 目的寄存器, <存儲(chǔ)器地址>

指令用于將存儲(chǔ)器中的一個(gè)32位的字?jǐn)?shù)據(jù)傳送到目的寄存器中。本指令通常用于將存儲(chǔ)器上的字?jǐn)?shù)據(jù)傳送到通用寄存器。

LDR R0,[R1]

將存儲(chǔ)器地址為R1的字?jǐn)?shù)據(jù)讀入寄存器R0

LDR R0,[R1,R2]

將存儲(chǔ)器地址為R1+R2的字?jǐn)?shù)據(jù)讀入寄存器R0。

LDR R0,[R1,#8]

將存儲(chǔ)器地址為R1+8的字?jǐn)?shù)據(jù)讀入寄存器R0

LDR R0, [R1,R2]!

將存儲(chǔ)器地址R1+R2的字?jǐn)?shù)據(jù)讀入寄存器R0,同時(shí)將新地址R1+R2寫入R1。

LDR R0, [R1,#5]!

將存儲(chǔ)器地址R1+5的字?jǐn)?shù)據(jù)讀入寄存器R0,同時(shí)將新地址R1+5寫入到R1。

LDR R0,[R1], R2

將存儲(chǔ)器地址為R1的字?jǐn)?shù)據(jù)讀入寄存器R0,并將新地址R1+R2寫入R1。

LDR R0,[R1,R2,LSL #2]!

將存儲(chǔ)器地址為R1+R2*4的字?jǐn)?shù)據(jù)讀入到寄存器R0中,并將新地址R1+R2*4寫入R1

LDR R0, [R1], R2, LSL #2

將存儲(chǔ)器地址為R1的字?jǐn)?shù)據(jù)讀入寄存器R0,并進(jìn)新地址R1+R2*4寫入R1。

LDR{條件}B 目的寄存器,<存儲(chǔ)器地址>

LDRB指令用于從存儲(chǔ)器中將一個(gè)8位的字節(jié)數(shù)據(jù)傳送到目的寄存器中,同時(shí)將寄存器的高24位清零。

LDRB R0,[R1]

LDRB R0,[R1,#8];將存儲(chǔ)器地址為R1+8的字節(jié)數(shù)據(jù)讀入寄存器R0,并將R0的高24位清零。

LDR{條件}H 目的寄存器,<存儲(chǔ)器地址>

LDRH指令用于從存儲(chǔ)器中將一個(gè)16位的半字?jǐn)?shù)據(jù)傳送到目的寄存器中,同時(shí)將寄存器的高16位清零。

LDRH R0,[R1]

LDRH R0,[R1,R2];將存儲(chǔ)器地址為R1+R2的半字?jǐn)?shù)據(jù)讀入寄存器R0,并將R0的高16位清零。

STR{條件} 源寄存器,<存儲(chǔ)器地址>

STR指令用于從源寄存器中將一個(gè)32位字?jǐn)?shù)據(jù)傳送到存儲(chǔ)器中。

STR R0,[R1], #8;將R0中的字?jǐn)?shù)據(jù)寫入以R1為地址的存儲(chǔ)器中,并將新地址R1+8寫入R1。

STR R0,[R1,#8];將R0中的字?jǐn)?shù)據(jù)寫入以R1+8為地址的存儲(chǔ)器中。

ARM微處理器所支持的批量數(shù)據(jù)加載/存儲(chǔ)指令可以一次在一片連續(xù)的存儲(chǔ)器單元和多個(gè)寄存器之間傳遞數(shù)據(jù),批量加載指令用于將一片連續(xù)的存儲(chǔ)單元的數(shù)據(jù)傳送到多個(gè)寄存器,批量數(shù)據(jù)存儲(chǔ)指令則完成相反的操作。

LDM批量數(shù)據(jù)加載指令

STM批量數(shù)據(jù)存儲(chǔ)指令

LDM{條件}{類型}基址寄存器{!},寄存器列表{^}

指令用于從由基址寄存器所指示的一片連續(xù)存儲(chǔ)器到寄存器列表所指示的多個(gè)寄存器之間傳送數(shù)據(jù),該指令的常見用途是將多個(gè)寄存器的內(nèi)容入?;虺鰲!F渲?,{類型}為以下幾種情況:

IA 每次傳送后地址加1;

IB 每次傳送前地址加1;

DA 每次傳送后地址減1;

DB 每次傳送前地址減1;

FD 滿遞減堆棧;

ED 空遞減堆棧;

FA 滿遞增堆棧;

EA 空遞增堆棧;

{!}為可選后綴,若選用該后綴,則當(dāng)數(shù)據(jù)傳送完畢之后,將最后的地址寫入基址寄存器,否則基址寄存器的內(nèi)容部改變?;芳拇嫫鞑辉试S為R15,寄存器列表可以為R0-R15的任意組合。

{^}為可選后綴,當(dāng)指令為LDM且寄存器列表中包含R15,選用該后綴時(shí)表示:除了正常的數(shù)據(jù)傳送之外,還將SPSR到CPSR。

STMFD R13!, {R0,R4-R12,LR}

將寄存器列表中的寄存器(R0,R4到R12,LR)存入堆棧。

LDMFD R13!, {R0,R4-R12,LR}

將堆棧內(nèi)容恢復(fù)到寄存器(R0,R4到R12,LR)。

數(shù)據(jù)交換指令

ARM微處理器所支持?jǐn)?shù)據(jù)交換指令能在存儲(chǔ)器和寄存器之間交換數(shù)據(jù)。

SWP 字?jǐn)?shù)據(jù)交換指令

SWPB 字節(jié)數(shù)據(jù)交換指令

SWP{條件} 目的寄存器, 源寄存器1,[源寄存器2]

SWP指令用于將源寄存器2所指向的存儲(chǔ)器中的字?jǐn)?shù)據(jù)傳送到目的寄存器中,同時(shí)將源寄存器1中的字?jǐn)?shù)據(jù)傳送到源寄存器2所指向的存儲(chǔ)器中,顯然,當(dāng)源寄存器1和目的寄存器為同一個(gè)寄存器時(shí),指令交換該寄存器和存儲(chǔ)器的內(nèi)容。

SWP R0,R1,[R2]

SWP R0,R0,[R1];該指令實(shí)現(xiàn)了將R1所指向的存儲(chǔ)器的字?jǐn)?shù)據(jù)與R0中的字?jǐn)?shù)據(jù)交換。

移位指令

ARM微處理器支持?jǐn)?shù)據(jù)的移位操作,移位操作在ARM指令集中不作為單獨(dú)的指令使用,它只能作為指令格式中是一個(gè)字段。

LSL logical shifter left

ASL arithmetic shifter left

LSR logical shifter right

ASR arithmetic shifter right

ROR rotate right

通用寄存器,LSL操作數(shù)

LSL可完成對(duì)寄存器中的內(nèi)容進(jìn)行邏輯左移操作,按操作數(shù)所指定的數(shù)量向左移位,低位用零來填充。其中,操作數(shù)可以是通用寄存器,也可以是立即數(shù)(0—31)。

MOV R0,R1,LSL#2

將R1中的內(nèi)容左移兩位后傳送到R0中。

通用寄存器,ROR 操作數(shù)

ROR可完成對(duì)通用寄存器中的內(nèi)容進(jìn)行循環(huán)右移的操作,按操作數(shù)所指定的數(shù)量向右循環(huán)移位,左端用右端移出的位來填充。其中,操作數(shù)可以是通用寄存器,也可以是立即數(shù)(0-31)。顯然,當(dāng)進(jìn)行32位的循環(huán)右移操作時(shí),通用寄存器中的值不改變。

MOV R0,R1,ROR#2

將R1中的內(nèi)容循環(huán)右移兩位后傳送到R0中。

異常產(chǎn)生的指令

ARM微處理器所支持的異常指令如下兩條:

SWI 軟件中斷指令

BKPT 斷點(diǎn)中斷指令

SWI{條件} 24位的立即數(shù)

SWI指令用于產(chǎn)生軟件中斷,以便用戶程序能調(diào)用操作系統(tǒng)的系統(tǒng)API。操作系統(tǒng)在SWI的異常處理程序中提供了相應(yīng)的系統(tǒng)服務(wù),指令中24位的立即數(shù)指定用戶程序調(diào)用的API類型。

SWI 0x02

該指令調(diào)用操作系統(tǒng)編號(hào)為02的系統(tǒng)例程。

偽指令

這些助記符與指令系統(tǒng)的助記符不同,沒有相對(duì)應(yīng)的操作碼,通常稱這些特殊指令助記符為偽指令,他們所完成的操作稱為偽操作。偽指令在源程序中的作用是為完成匯編程序作各種準(zhǔn)備工作,這些偽指令僅在匯編過程中起作用,一旦匯編結(jié)束,偽指令的使命就完成。

ARM中有如下幾種偽指令:符號(hào)定義偽指令、數(shù)據(jù)定義偽指令、匯編控制偽指令、宏指令以及其他偽指令。

符號(hào)定義偽指令用于定義ARM匯編程序中的變量、對(duì)變量賦值以及定義寄存器的別名等操作。常見的符號(hào)定義偽指令有如下幾種:

定義全局變量的GBLA、GBLL和GBLS

定義局部變量的LCLA、LCLL和LCLS

對(duì)變量賦值的SETA、SETL、SETS

為通用寄存器列表定義名稱的RLIST

GBLA:定義一個(gè)全局的數(shù)字變量,并初始化為0;

GBLL:定義一個(gè)全局的邏輯變量,并初始化為F(假);

GBLS:定義一個(gè)全局的字符串變量,并初始化為空;

以上三條偽指令用于定義全局變量,因此在整個(gè)程序范圍內(nèi)變量名必須唯一。

GBLA Test1

定義一個(gè)全局的數(shù)字變量,變量名為Test1

Test1 SETA 0xaa

進(jìn)該變量賦值為0xaa

GBLL Test2

定義一個(gè)全局的邏輯變量,變量名為Test2

Test2 SETL {TRUE}

將該變量賦值為真

GBLS Test3

定義一個(gè)全局的字符串變量,變量名為Test3

Test3 SETS “testing”

將該變量賦值為“testing”

名稱 RLIST {寄存器列表}

RLIST 偽指令用于對(duì)一個(gè)通用寄存器列表定義名稱,使用該偽指令定義的列表名稱可在ARM指令LDM/STM中使用。在LDM/STM指令中,列表中的寄存器訪問次序?yàn)楦鶕?jù)寄存器的編號(hào)由低到高,而與列表中的寄存器排序無關(guān)。

Reglist RLIST {R0-R5,R8,R10}:將寄存器列表名稱定義為Reglist,可在ARM指令LDM/STM中通過該名稱訪問寄存器列表。

數(shù)據(jù)定義偽指令一般用于為特定的數(shù)據(jù)分配存儲(chǔ)單元,同時(shí)可完成已分配存儲(chǔ)單元的初始化。

DCB DCW DCD DCFD DCFS DCQ SPACE MAP FIELD

標(biāo)號(hào) DCB 表達(dá)式

DCB偽指令用于分配一片連續(xù)的字節(jié)存儲(chǔ)單元并用偽指令中指定的表達(dá)式初始化。其中,表達(dá)式可以為0-255的數(shù)字或字符串。DCB也可用“=”代替。

Str DCB “This is a test!”:分配一片連續(xù)的字節(jié)存儲(chǔ)單元并初始化。

標(biāo)號(hào) SPACE 表達(dá)式

SPACE偽指令用于分配一片連續(xù)的存儲(chǔ)區(qū)域并初始化為0.其中,表達(dá)式為要分配的字節(jié)數(shù)。SPACE也可用“%”代替。

DateSpace SPACE 100;分配連續(xù)100字節(jié)的存儲(chǔ)單元并初始化為0.

MAP 表達(dá)式 {基址寄存器}

MAP偽指令用于定義一個(gè)結(jié)構(gòu)化的內(nèi)存表的首地址。MAP也可用“^”代替。表達(dá)式可以為程序中的標(biāo)號(hào)或數(shù)學(xué)表達(dá)式,基址寄存器為可選項(xiàng),當(dāng)基址寄存器選項(xiàng)不存在時(shí),表達(dá)式的值即為內(nèi)存表的首地址,當(dāng)該選項(xiàng)存在時(shí),內(nèi)存表的首地址為表達(dá)式的值與基址寄存器的和。MAP偽指令通常與FIELD偽指令配合使用來定義結(jié)構(gòu)化的內(nèi)存表。

MAP 0x100,R0

定義結(jié)構(gòu)化內(nèi)存表首地址的值為0x100+R0。

標(biāo)號(hào) FIELD 表達(dá)式

FIELD偽指令用于定義一個(gè)結(jié)構(gòu)化內(nèi)存表中的數(shù)據(jù)域。FILED也可用“#”代替。表達(dá)式的值為當(dāng)前數(shù)據(jù)域在內(nèi)存表中所占的字節(jié)數(shù)。FIELD偽指令常與MAP偽指令配合使用來定義結(jié)構(gòu)化的內(nèi)存表。MAP偽指令定義內(nèi)存表的首地址,F(xiàn)IELD偽指令定義內(nèi)存表中的各個(gè)數(shù)據(jù)域,并可以為每個(gè)數(shù)據(jù)域指定一個(gè)標(biāo)號(hào)供其他的指令引用。

MAP 0x100;定義結(jié)構(gòu)化內(nèi)存表首地址的值為0x100

AFIELD 16:定義A的長度為16字節(jié),位置為0x100

BFIELD 32;定義B的長度為32字節(jié),位置為0x110

SFIELD256;定義C的長度為256字節(jié),位置0x130

匯編控制偽指令:

IF ELSE ENDIF

WHILE WEND

MACRO MEND

MEXIT

WHILE 邏輯表達(dá)式

指令序列

WEND

其他偽指令:

AREA 段名 屬性1,屬性2,......

AREA偽指令用于定義一個(gè)代碼段或數(shù)據(jù)段。其中,段名若以數(shù)字開頭,則該段名需用“|”括起來,如|1_test|。屬性字段表示該代碼段的相關(guān)屬性,多個(gè)屬性用逗號(hào)分隔。常用屬性如下:

CODE:用于定義代碼段,默認(rèn)為READONLY。

DATA:用于定義數(shù)據(jù)段,默認(rèn)為READWRITE。

READONLY:定義本段為只讀,代碼段默認(rèn)為READONLY。

READWRITE;指定本段為可讀可寫,數(shù)據(jù)段的默認(rèn)屬性READWRITE。

ALIGN屬性,使用方式為:

ALIGN 表達(dá)式

在默認(rèn)時(shí),ELF的代碼段和數(shù)據(jù)段是按字對(duì)齊的。

一個(gè)匯編語言程序至少要包含一個(gè)段,當(dāng)程序太長時(shí),也可以將程序分為多個(gè)代碼段和數(shù)據(jù)段。

AREA Init,CODE,READONLY

該偽指令定義了一個(gè)代碼段,段名為Init,屬性為只讀。

ALIGN {表達(dá)式{偏移量}}

ALIGN偽指令可通過添加填充字節(jié)的方式,使當(dāng)前位置滿足一定的對(duì)齊方式。其中,表達(dá)式的值用于指定對(duì)齊方式,可能的取值為2的冪,如1,2,4,8,16等。若未指定表達(dá)式,則將當(dāng)前位置對(duì)齊到下一個(gè)字的位置。偏移量也為一個(gè)數(shù)字表達(dá)式,若使用該字段,則當(dāng)前位置的對(duì)齊方式為:2的表達(dá)式次冪+偏移量。

AREA Init,CODE,READONLY,ALIGN=3

指定后面的指令為8字節(jié)對(duì)齊。

CODE16(或CODE32)

CODE16偽指令通知編譯器,其后的指令序列為16位的Thumb指令。CODE32偽指令通知編譯器,其后的指令序列為32位的ARM指令。因此,在使用ARM指令和Thumb指令混合編程的代碼里,可用這兩條偽指令進(jìn)行切換,但注意他們只通知編譯器其后指令的類型,并不能對(duì)處理器進(jìn)行狀態(tài)的切換。

ENTRY

ENTRY偽指令用于指定匯編程序的入口點(diǎn),在一個(gè)完整的匯編程序中至少要有一個(gè)ENTRY(也可有多個(gè),當(dāng)有多個(gè)ENTRY時(shí),程序的真正入口點(diǎn)由鏈接器指定),但在一個(gè)源文件里最多只能有一個(gè)ENTRY。

名稱 EQU 表達(dá)式{類型}

EQU偽指令用于為程序中的常量、標(biāo)號(hào)等定義一個(gè)等效的字符名稱,類似于C語言中的#define。其中EQU可用“*”代替。

Test EQU 50

Addr EQU 0x55,CODE32;定義Addr的值為0x55,且該處為32位的ARM指令。

EXPORT 標(biāo)號(hào)

EXPORT偽指令用于在程序中聲明一個(gè)全局的標(biāo)號(hào),該標(biāo)號(hào)可在其他的文件中引用。EXPORT可用GLOBAL代替。標(biāo)號(hào)在程序中區(qū)分大小寫。

AREA Init,CODE,READONLY

EXPORT Stest

聲明一個(gè)可全局引用的標(biāo)號(hào)Stest

IMPORT 標(biāo)號(hào)

IMPORT偽指令用于通知編譯器要使用的標(biāo)號(hào)在其他的源文件中定義,但要在當(dāng)前源文件中引用。標(biāo)號(hào)在程序中區(qū)分大小寫。

AREA Init,CODE,READONLY

IMPORT Main

通知編譯器當(dāng)前文件要引用標(biāo)號(hào)Main,但Main在其他源文件中定義

END

END偽指令用于通知編譯器已經(jīng)到了源程序的結(jié)尾。



關(guān)鍵詞: ARM指令集匯

評(píng)論


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

關(guān)閉