<meter id="pryje"><nav id="pryje"><delect id="pryje"></delect></nav></meter>
          <label id="pryje"></label>

          新聞中心

          ARM指令集詳解2

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

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

          本文引用地址:http://www.ex-cimer.com/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)容入棧或出棧。其中,{類型}為以下幾種情況:

          IA 每次傳送后地址加1;

          IB 每次傳送前地址加1;

          DA 每次傳送后地址減1;

          DB 每次傳送前地址減1;

          FD 滿遞減堆棧;

          ED 空遞減堆棧;

          FA 滿遞增堆棧;

          EA 空遞增堆棧;

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

          {^}為可選后綴,當(dāng)指令為L(zhǎng)DM且寄存器列表中包含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ù)量向左移位,低位用零來(lái)填充。其中,操作數(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)移位,左端用右端移出的位來(lái)填充。其中,操作數(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)的助記符不同,沒(méi)有相對(duì)應(yīng)的操作碼,通常稱這些特殊指令助記符為偽指令,他們所完成的操作稱為偽操作。偽指令在源程序中的作用是為完成匯編程序作各種準(zhǔn)備工作,這些偽指令僅在匯編過(guò)程中起作用,一旦匯編結(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指令中,列表中的寄存器訪問(wèn)次序?yàn)楦鶕?jù)寄存器的編號(hào)由低到高,而與列表中的寄存器排序無(wú)關(guān)。

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

          數(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偽指令配合使用來(lái)定義結(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偽指令配合使用來(lái)定義結(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的長(zhǎng)度為16字節(jié),位置為0x100

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

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

          匯編控制偽指令:

          IF ELSE ENDIF

          WHILE WEND

          MACRO MEND

          MEXIT

          WHILE 邏輯表達(dá)式

          指令序列

          WEND

          其他偽指令:

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

          AREA偽指令用于定義一個(gè)代碼段或數(shù)據(jù)段。其中,段名若以數(shù)字開頭,則該段名需用“|”括起來(lái),如|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è)匯編語(yǔ)言程序至少要包含一個(gè)段,當(dāng)程序太長(zhǎng)時(shí),也可以將程序分為多個(gè)代碼段和數(shù)據(jù)段。

          AREA Init,CODE,READONLY

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

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

          ALIGN偽指令可通過(guò)添加填充字節(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語(yǔ)言中的#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)閉
          看屁屁www成人影院,亚洲人妻成人图片,亚洲精品成人午夜在线,日韩在线 欧美成人 (function(){ var bp = document.createElement('script'); var curProtocol = window.location.protocol.split(':')[0]; if (curProtocol === 'https') { bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; } else { bp.src = 'http://push.zhanzhang.baidu.com/push.js'; } var s = document.getElementsByTagName("script")[0]; s.parentNode.insertBefore(bp, s); })();