一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

ARM匯編偽指令

 waston 2018-05-11

ARM 匯編程序的由機(jī)器指令,偽指令和宏指令組成。偽指令不像機(jī)器指令那樣在處理器運(yùn)行期間由機(jī)器執(zhí)行,而是匯編程序?qū)υ闯绦騾R編期間由匯編程序處理。在前面的指令集章節(jié)中,我們已經(jīng)接觸了幾條常用到的偽指令,如ADR 、ADRL、LDR、NOP 等,把它們和指令集一起介紹是因?yàn)樗鼈冊(cè)趨R編時(shí)會(huì)被合適的機(jī)器指令代替,實(shí)現(xiàn)真正機(jī)器指令操作。宏是一段獨(dú)立的程序代碼,它是通過(guò)偽指令定義的,在程序中使用宏指令即可調(diào)用宏。當(dāng)程序被匯編時(shí),匯編程序?qū)?duì)每個(gè)調(diào)用進(jìn)行展開,用宏定義取代源程序中的宏指令。

A.4.1  符號(hào)定義偽指令

符號(hào)定義偽指令用于定義ARM 匯編程序的變量,對(duì)變量進(jìn)行賦值以及定義寄存器名稱,該類偽指令如下:

全局變量聲明:GBLA、GBLL 和GBLS。

局部變量聲明:LCLA、LCLL 和LCLS。

變量賦值: SETA、SETL 和SETS。

為一個(gè)通用寄存器列表定義名稱:RLIST。

為一個(gè)協(xié)處理器的寄存器定義名稱:CN。

為一個(gè)協(xié)處理定義名稱: CP。

為一個(gè)VFP 寄存器定義名稱:DN 和SN。

為一個(gè)FPA 浮點(diǎn)寄存器定義名稱:

GBLA、GBLL、GBLS---全局變量聲明偽指令 

GBLA 偽指令用于聲明一個(gè)全局的算術(shù)變量,并將其初始化為0。

GBLL 偽指令用于聲明一個(gè)全局的邏輯變量,并將其初始化為{FALSE}

GBLS 偽指令用于聲明一個(gè)全局的字符串變量,并將其初始化為空字符串“”。

偽指令格式:

GBLA variable

GBLL variable

GBLS variable

其中:variable 定義的全局變量名,在其作用范圍內(nèi)必須惟一。全局變量的作用范圍為包含該變量的源程序。

偽指令應(yīng)用舉例如下:

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

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

LCLA、LCLL、LCLS ----局部變量聲明偽指令,用于宏定義的體中。

LCLA 偽指令用于聲明一個(gè)局部的算術(shù)變量,并將其初始化為0。

LCLL 偽指令用于聲明一個(gè)局部的邏輯變量,并將其初始化為{FALSE}。

LCLS 偽指令用于聲明一個(gè)局部的字符串變量,并將其初始化為空字符串“”。

偽指令格式:

LCLA variable

LCLL variable

LCLS variable

其中:variable 定義的局部變量名。在其作用范圍內(nèi)必須惟一。局部變量的作用范圍為包含該局部變量只能在宏中進(jìn)行聲明及使用。

偽指令應(yīng)用舉例如下:

MACRO ;聲明一個(gè)宏

SENDDAT $dat ;宏的原型

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

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

MEND

SETA、SETL、SETS----變量賦值偽指令。用于對(duì)已定義的全局變量,局部變量賦值

SETA 偽指令用于給一個(gè)全局/局部的算術(shù)變量賦值。

SETL 偽指令用于給一個(gè)全局/局部的邏輯變量賦值。

SETS 偽指令用于給一個(gè)全局/局部的字符串變量賦值。

偽指令格式:

variable_a SETA expr_a

variable_l SETL expr_l

variable_s SETS expr_s

其中:variable_a 算術(shù)變量。用GBLA、LCLA 偽指令定義的變量。

expr_a 賦值的常數(shù)。

variable_l 邏輯變量。用GBLL、LCLL 偽指令定義的變量。

expr_l 邏輯值,即{TRUE}或{FALSE}。

variable_s 字符串變量。用GBLS、LCLS 偽指令定義的變量。

expr_s 賦值的字符串。

偽指令應(yīng)用舉例如下:

GBLS ErrStr

ErrStr SETS “No,semaphone”

RLIST-----  RLIST 為一個(gè)通用寄存器列表定義名稱

偽指令格式如下:

name RLIST {reglist}

其中:name 要定義的寄存器列表的名稱。

reglist 通用寄存器列表。

偽指令應(yīng)用舉例如下:

LoReg RLIST {R0-R7} ;定義寄存器列表LoReg

STMFD SP!,LoReg ;保存寄存器列表LoReg

CN ---- CN 為一個(gè)協(xié)處理器的寄存器定義名稱。

CN 為一個(gè)協(xié)處理器的寄存器定義名稱。

偽指令格式:

name CN expr

其中:name 要定義的協(xié)處理器的寄存器名稱。

expr 協(xié)處理器的寄存器編號(hào),數(shù)值范圍為0~15。

偽指令應(yīng)用舉例如下:

MemSet CN l ;將協(xié)處理的寄存器l 名稱定義為MemSet

CP ----CP為一個(gè)協(xié)處理器定義的名稱

偽指令格式:

name CP expr

其中:name 要定義的協(xié)處理器名稱。

expr 協(xié)處理器的編號(hào),數(shù)值范圍為0~15。

偽指令應(yīng)用舉例如下:

DivRun CN 5 ;將協(xié)處理器5 名稱定義為DivRun

DN、SN  ---DN 和SN 為VFP 的寄存器的名稱定義的偽指令

DN 為一個(gè)雙精度原VFP 寄存器定義名稱。

SN 為一個(gè)單精度的VFP 寄存器定義名稱。

偽指令格式:

name DN expr

name SN expr

其中:name 要定義的VFP 寄存器名稱。

expr 雙精度的VFP 寄存器編號(hào)為0~15,單精度的VFP 寄存器編號(hào)為0~31。

偽指令應(yīng)用舉例如下:

cdn DN 1 ;將VFP 雙精度寄存器1 名稱定義為cdn

rex SN 3 ;將VFP 單精度寄存器3 名稱定義為rex

FN --- FN 為一個(gè)FPA 浮點(diǎn)寄存器定義名稱

偽指令格式:

name FN expr

其中:name 要定義的浮點(diǎn)寄存器名稱。

expr 浮點(diǎn)寄存器的編號(hào),值為0~7。

偽指令應(yīng)用舉例如下:

ibq FN l ;將浮點(diǎn)寄存器l 名稱定義為ibq

A.4.2  數(shù)據(jù)定義偽指令

數(shù)據(jù)定義偽指令用于數(shù)據(jù)表定義,文字池定義,數(shù)據(jù)空間分配等。該類偽指令如下:

聲明一個(gè)文字池:LTORG。

定義一個(gè)結(jié)構(gòu)化的內(nèi)存表的首地址:MAP。

定義結(jié)構(gòu)化內(nèi)存表中的一個(gè)數(shù)據(jù)域:FIELD。

分配一塊內(nèi)存空間,并用0 初始化:SPACE。

分配一段字節(jié)的內(nèi)存單元,并用指定的數(shù)據(jù)初始化:DCB。

分配一段字的內(nèi)存單元,并用指定的數(shù)據(jù)初始化:DCD 和DCDU。

分配一段字的內(nèi)存單元,將每個(gè)單元的內(nèi)容初始化為該單元相對(duì)于靜態(tài)基址寄存器的偏移量:DCDO。

分配一段雙字的內(nèi)存單元,并用雙精度的浮點(diǎn)數(shù)據(jù)初始化:DCFD 和DCFDU。

分配一段字的內(nèi)存單元,并用單精度的浮點(diǎn)數(shù)據(jù)初始化:DCFS 和DCFSU。

分配一段字的內(nèi)存單元,并用單精度的浮點(diǎn)數(shù)據(jù)初始化,指定內(nèi)存單元存放的是代碼,而不是數(shù)據(jù):DCI。

分配一段雙字的內(nèi)存單元,并用64 位整數(shù)數(shù)據(jù)初始化:DCQ 和DCQU。

分配一段半字的內(nèi)存單元,并用指定的數(shù)據(jù)初始化:DCW 和DCWU。

LTORG------  LTORG 用于聲明一個(gè)文字池

在使用LDR 偽指令時(shí),要在適當(dāng)?shù)牡刂芳尤隠TORG 聲明文字池,這樣就會(huì)把要加載的數(shù)據(jù)保存在文字池內(nèi),再用ARM 的加載指令讀出數(shù)據(jù)。(若沒(méi)有使用LTORG 聲明文字池,則匯編器會(huì)在程序末尾自動(dòng)聲明。)

偽指令格式:

LTORG

偽指令應(yīng)用舉例如下:

LDR R0,=0x12345678

ADD R1,R1,R0

MOV PC,LR

LTORG ;聲明文字池,此地址存儲(chǔ)0x12345678

… ;其它代碼

LTORG 偽指令常放在無(wú)條件跳轉(zhuǎn)指令之后,或者子程序返回指令之后,這樣處理器就不會(huì)錯(cuò)誤地將文字池中的數(shù)據(jù)當(dāng)作指令來(lái)執(zhí)行。

MAP-------MAP 用于定義一個(gè)結(jié)構(gòu)化的內(nèi)存表的首地址

此時(shí),內(nèi)存表的位置計(jì)數(shù)器{VAR}設(shè)置為該地址值{VAR}為匯編器的內(nèi)置變量。^與MAP 同義。

偽指令格式:

MAP expr,{base_register}

其中:expr 數(shù)字表達(dá)式或程序中的標(biāo)號(hào)。當(dāng)指令中沒(méi)有

base_register 時(shí),expr 即為結(jié)構(gòu)化內(nèi)存表的首地址。

base_register 一個(gè)寄存器。當(dāng)指令中包含這一項(xiàng)時(shí),結(jié)構(gòu)化內(nèi)存表的首地址為expr 與base_register 寄存器值的和。

偽指令應(yīng)用舉例如下:

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

Timer FIELD 4 ;定義數(shù)據(jù)域Timer,長(zhǎng)度為4 字節(jié)

Attrib FIELD 4 ;定義數(shù)據(jù)域Attrib,長(zhǎng)度為4 字節(jié)

String FIELD 100 ;定義數(shù)據(jù)域String,長(zhǎng)度為100 字節(jié)

ADR R9,DataStart ;設(shè)置R9 的值,即設(shè)置結(jié)構(gòu)化的內(nèi)存表地址

LDR R0,Atrrib ;相當(dāng)于LDR,R0,[R9,#4]

MAP 偽指令和FIELD 偽指令配合使用,用于定義結(jié)構(gòu)化的內(nèi)存表結(jié)構(gòu)。MAP 偽指令中的base-register 寄存器的值對(duì)于其后所有的FIELD 偽指令定義的數(shù)據(jù)域是默認(rèn)使用的,直到遇到新的包含base-register 項(xiàng)的MAP 偽指令。

FIELD------FIELD 用于定義一個(gè)結(jié)構(gòu)化內(nèi)存表中的數(shù)據(jù)域。#與FIELD 同義。         偽指令格式:

{tabel} FIELD expr

其中:label 當(dāng)指令中包含這一項(xiàng)時(shí),label 的值為當(dāng)前內(nèi)存表的位置計(jì)數(shù)器{VAR}的值,匯編編譯器處理了這條FIELD 偽指令后,內(nèi)存表計(jì)數(shù)器的值將加上expr。

expr 表示本數(shù)據(jù)域在內(nèi)存表中所占用的字節(jié)數(shù)。

偽指令應(yīng)用舉例如下:

MAP 0x40003000 ;內(nèi)存表的首地址為0x40003000

count1 FIELD 4 ;定義數(shù)據(jù)域count1,長(zhǎng)度為4 字節(jié)

count2 FIELD 4 ;定義數(shù)據(jù)域count2,長(zhǎng)度為4 字節(jié)

count3 FIELD 4 ;定義數(shù)據(jù)域count3,長(zhǎng)度為4 字節(jié)

LDR R1,count1 ;R1=[0x40003000+0x00]

STR R1,count2 ;[0x40003000+0x00]=R1

MAP、FIELD 偽指令僅僅是定義數(shù)據(jù)結(jié)構(gòu),它們并不實(shí)際分配內(nèi)存單元。

SPACE--------SPACE 用于分配一塊內(nèi)存單元,并用0 初始化。%與SPACE 同義。         偽指令格式:

{label} SPACE expr

其中:label 內(nèi)存塊起始地址標(biāo)號(hào)。

expr 所要分配的內(nèi)存字節(jié)數(shù)。

偽指令應(yīng)用舉例如下:

AREA DataRA,DATA,READWROTE ;聲明一數(shù)據(jù)段,名為DataRAM

DataBuf SPACE 1000 ;分配1000 字節(jié)空間

DCB------DCB 用于分配一段字節(jié)內(nèi)存單元,并用偽指令中的expr 初始化。一般可用來(lái)定義數(shù)據(jù)表格,或文字符串。=與DCB 同義。         偽指令格式:

{label} DCB expr{,expr}{,expr}…

其中:label 內(nèi)存塊起始地址標(biāo)號(hào)。

expr 可以為-128~255 的數(shù)值或字符串。內(nèi)存分配的字節(jié)數(shù)由expr 個(gè)數(shù)決定。

偽指令應(yīng)用舉例如下

DISPTAB DCB 0x33,0x43,0x76,0x12

DCB -120,20,36,55

ERRSTR DCB “Send,data is error!”,0

DCD 和DCDU-------DCD 用于分配一段字內(nèi)存單元,并用偽指令中的expr 初始化。DCD 偽指令分配的內(nèi)存需要字對(duì)齊,一般可用來(lái)定義數(shù)據(jù)表格或其它常數(shù)。         DCDU 用于分配一段字內(nèi)存單元,并用偽指令中的expr 初始化。DCD 偽指令分配的內(nèi)存不需要字對(duì)齊,一般可用來(lái)定義數(shù)據(jù)表格或其它常數(shù)。

偽指令格式:

{label} DCD expr{,expr}{,expr}…

{label} DCDU expr{,expr}{,expr}…

其中:label 內(nèi)存塊起始地址標(biāo)號(hào)。

expr 常數(shù)表達(dá)式或程序中的標(biāo)號(hào)。內(nèi)存分配字節(jié)數(shù)由expr 個(gè)數(shù)決定。

偽指令應(yīng)用舉例如下:

Vectors

LDR PC,ReserAddr

LDR PC,UndefinedAddr

ResetAddr DCD Reset

UndefinedAddr DCD Undefined

Reset

Undefined

DCDO--------- DCDO 用于分配一段字內(nèi)存單元。并將每個(gè)單元的內(nèi)容初始化為該單元相對(duì)于靜態(tài)基址寄存器的偏移量。

DCDO 偽指令作為基于靜態(tài)基址寄存器R9 的偏移量分配內(nèi)存單元。DCDO 偽指令分配的內(nèi)存需要字對(duì)齊。

偽指令格式:

{label} DCDO expr{,expr}{,expr}…

其中:label 內(nèi)存塊起始地址標(biāo)號(hào)。

expr 地址偏移表達(dá)式或程序中的標(biāo)號(hào)。內(nèi)存分配的字?jǐn)?shù)由expr 個(gè)數(shù)決定。

偽指令應(yīng)用舉例如下:

IMPORT externsym

DCDO externsym ;分配32 位的字單元,其值為標(biāo)號(hào)externsym 基于R9 的偏移

DCFD 和DCFDU-----DCFD 用于分配一段雙字的內(nèi)存單元,并用雙精度的浮點(diǎn)數(shù)據(jù)fpliteral 初始化。

每個(gè)雙精度的浮點(diǎn)數(shù)占據(jù)兩個(gè)字單元。DCFD 偽指令分配的內(nèi)存需要字對(duì)齊。

DCFDU 具有DCFD 同樣的功能,但分配的內(nèi)存不需要字對(duì)齊。

偽指令格式:

{label} DCFD fpliteral{,fpliteral}{,fpliteral}…

{label} DCFDU fpliteral{,fpliteral}{,fpliteral}…

其中:label 內(nèi)存塊起始地址標(biāo)號(hào)。

fpliteral 雙精度的浮點(diǎn)數(shù)。

偽指令應(yīng)用舉例如下:

DCFD 2E30,-3E-20

DCFDU -.1,1000,2.1E18

DCFS 和DCFSU----- DCFS 用于分配一段字的內(nèi)存單元,并用單精度的浮點(diǎn)數(shù)據(jù)fpliteral 初始化。

每個(gè)單精度的浮點(diǎn)數(shù)占據(jù)一個(gè)字單元。DCFD 偽指令分配的內(nèi)存需要字對(duì)齊。

DCFSU 具有DCFS 同樣的功能,但分配的內(nèi)存不需要字對(duì)齊。

偽指令格式:

{label} DCFS fpliteral{,fpliteral}{,fpliteral}…

{label} DCFSU fpliteral{,fpliteral}{,fpliteral}…

其中:label 內(nèi)存塊起始地址標(biāo)號(hào)

fpliteral 單精度的浮點(diǎn)數(shù)。

偽指令應(yīng)用舉例如下:

DCFS 1.1E2,-1.3E10,0.0999

DCI在ARM 代碼中,DCI 用于分配一段字節(jié)的內(nèi)存單元,用指定的數(shù)據(jù)expr 初始化。指定內(nèi)存單元存放的是代碼,而不是數(shù)據(jù)。在Thumb 代碼中,DCI 用于分配一段半字節(jié)的內(nèi)存單元,用指定的數(shù)據(jù)expr 初始化。指定內(nèi)存單元存放的是代碼,而不是數(shù)據(jù)。

偽指令格式:

{label} DCI expr

其中:label 內(nèi)存塊起始地址標(biāo)號(hào)。

expr 可為數(shù)字表達(dá)式。

DCI 偽指令和DCD 偽指令非常類似,不同之處在于DCI 分配的內(nèi)存中的數(shù)據(jù)被標(biāo)識(shí)為指令??捎糜谕ㄟ^(guò)宏指令業(yè)定義處理器不支持的指令。

偽指令應(yīng)用舉例如下:

MACRO ;宏定義(定義NEWCMN Rd,Rn 指令)

NEWCMN $Rd,$Rm ;宏名為NEWCMN,參數(shù)為Rd 和Rm

DCI 0xe16a0e20:OR:($Rd:SHL:12):OR:$Rm

MEND

DCQ 和DCQUDCQ 用于分配一段雙字的內(nèi)存單元,并用64 位的整數(shù)數(shù)據(jù)literal 初始化。DCQ 偽指令分配的內(nèi)存需要字對(duì)齊。DCQU 具有DCQ 同樣的功能,但分配的內(nèi)存不需要字對(duì)齊。

偽指令格式:

{label} DCQ {-}literal{,{-}{literal}}…

{label} DCQU {-}literal{,{-}{literal}}…

其中:label 內(nèi)存塊起始地址標(biāo)號(hào)。

literal 64 位的數(shù)字表達(dá)式。取值范圍為0~264-1 當(dāng)literal前有“.”號(hào)時(shí),取值范圍為-263~-1 之間。

偽指令應(yīng)用舉例如下:

DCQU 1234,-76568798776

DCW 和DCWUDCW 用于分配一段字的內(nèi)存單元,并用指定的數(shù)據(jù)expr 初始化。DCW 偽指令分配的內(nèi)存需要字對(duì)齊。DCWU 具有DCW 同樣的功能,但分配的內(nèi)存不需要字對(duì)齊。

偽指令格式:

{label} DCW expr{,expr}{,expr}…

{label} DCWU expr{,expr}{,expr}…

其中:label 內(nèi)存塊起始地址標(biāo)號(hào)。

expr 數(shù)字表達(dá)式,取值范圍為-32768~65535。

偽指令應(yīng)用舉例如下:

DCW -592,123,6756

報(bào)告?zhèn)沃噶?/p>

報(bào)告?zhèn)沃噶钣糜趨R編報(bào)告指示。該類偽指令如下:

斷言錯(cuò)誤:ASSERT。

匯編診斷信息顯示:INFO。

設(shè)置列表選項(xiàng):OPT。

插入標(biāo)題:TTL 和SUBT。

ASSERTASSERT 為斷言錯(cuò)誤偽指令。在匯編編譯器對(duì)匯編程序的第二遍掃描中,如果其中SSERT 條件不成立,ASSERT 偽指令將報(bào)告該錯(cuò)誤信息。

偽指令格式:

ASSERT Logical_expr

其中:Logical_expr 用于斷言的邏輯表達(dá)式

偽指令應(yīng)用舉例如下:

ASSERT Top<>Temp ;斷言Top 不等于Temp

INFO-----   匯編診斷信息顯示偽指令,在匯編器處理過(guò)程中的第一遍掃描或第一遍掃描時(shí)報(bào)告診斷信息。         偽指令格式:

INFO numeric_expr,string_expr

其中:numeric_expr 數(shù)據(jù)表達(dá)式。若值為0,則在第一遍掃描時(shí)報(bào)告診斷信息。否則在第一遍掃描時(shí)報(bào)告診斷信息。

strint_expr 要顯示的字串

偽指令應(yīng)用舉例如下:

INFO 0,”Version 0。1” ;在第二遍掃描時(shí),報(bào)告版本信息

if cont1 > cont2 ;如果cont1 > cont2

INFO 1,”cont1 > cont2” ;則在第一遍掃描時(shí)報(bào)告”cont1 > cont2”

OPT-----         設(shè)置列表選項(xiàng)偽指令。通過(guò)OPT 偽指令可以在源程序中設(shè)置列表選項(xiàng)。         偽指令格式:

OPI n

其中n 所設(shè)置的選項(xiàng)的編碼如下:

1 設(shè)置常規(guī)列表選項(xiàng)

2 關(guān)閉常規(guī)列表選項(xiàng)

4 設(shè)置分頁(yè)符,在新的一頁(yè)開始顯示

8 將行號(hào)重新設(shè)置為0

16 設(shè)置選項(xiàng),顯示SET、GBL、LCL 偽指令

32 設(shè)置選項(xiàng),不顯示SET、GBL、LCL 偽指令

64 設(shè)置選項(xiàng),顯示宏展開

128 設(shè)置選項(xiàng),不顯示宏展開

256 設(shè)置選頂,顯示宏調(diào)用

512 設(shè)置選項(xiàng),不顯示宏調(diào)用

1024 設(shè)置選頂,顯示第一遍掃描列表

2048 設(shè)置選項(xiàng),不顯示第一遍掃描列表

4096 設(shè)置選項(xiàng)目,顯示條件匯編偽指令

8192 設(shè)置選項(xiàng),不顯示條件匯編偽指令

16384 設(shè)置選項(xiàng),顯示MEND 偽指令

32768 設(shè)置選項(xiàng),不顯示MEND 偽

默認(rèn)情況下,-list 選項(xiàng)生成常規(guī)的列表文件,包括變量聲明,宏展開,條件匯編偽指令及MEND 偽指令,而且列表文件只是在第二遍掃描時(shí)給出,通過(guò)OPT 偽指令,可以在源程序中改變默認(rèn)的選項(xiàng)。

偽指令應(yīng)用舉例如下:

… ;代碼

OPT 512 ;不顯示宏調(diào)用

… ;代碼

TTL 和SUBT   TTL 和SUBT 為插入標(biāo)題偽指令TTL 偽指令在列表文件的每一頁(yè)的開頭插入一個(gè)標(biāo)題。該TTL 偽指令的作用在其后的每一頁(yè),直到遇到新的TTL 偽指令。 SUBT 偽指令在列表文件的每頁(yè)的開頭第一個(gè)子標(biāo)題。該SUBT 偽指令的作用在其后的每一頁(yè),直到遇到新的SUBT 偽指令。

偽指令格式:

TTL title

SUBT subtitle

其中:title 標(biāo)題名。

subtitle 子標(biāo)題名。

偽指令應(yīng)用舉例如下:

TTL mainc

SUBT subc con

A.4.3  匯編控制偽指令

匯編控制偽指令用于條件匯編、宏定義、重復(fù)匯編控制等。該類偽指令如下:

條件匯編控制: IF、ELSE 和ENDIF

宏定義: MACRO 和MEND

重復(fù)匯編: WHILE 及WEND

IF、ELSE 和ENDIFIF 、ELSE 和ENDIF 偽指令能夠根據(jù)條件把一段代碼包括在匯編程序內(nèi)或?qū)⑵渑懦诔绦蛑狻?nbsp;[與IF 同義,|與ELSE 同義,]與ENDIF 同義。

偽指令格式:

IF logical_expr

;指令或偽指令代碼段1

ELSE

;指令或偽指令代碼段2

ENDIF

其中:logical_expr 用于控制的邏輯表達(dá)式。若條件成立,則代碼段落在匯編源程序中有效。若條件不成立,代碼段1 無(wú)效,同時(shí)若使用ELSE 偽指令,代碼段有效。

偽指令應(yīng)用舉例如下:

IF {CONFIG}=16

BNE __rt_udiv_1

LDR R0,=__rt_div0

BX R0

ELSE

BEQ __rt_div0

ENDIF

IF、ELSE 和ENDIF 偽指令是可以嵌套使用的。

MACRO 和MENDMACRO 和MEND 偽指令用于宏定義。MACRO 標(biāo)識(shí)宏定義的開始,MEND 標(biāo)識(shí)宏定義的結(jié)束。用MACRO 及MEND 定義的一段代碼,稱為宏定義體。這樣在程序中就可以通過(guò)宏指令多次調(diào)用該代碼段。

偽指令格式:

MACRO

{$label} macroname {$parameter} {$parameter}…

;宏定義體。

MEND

其中:$label 宏指令被展開時(shí),label 可被替換成相應(yīng)的符號(hào),通常為一個(gè)標(biāo)號(hào)在一個(gè)符號(hào)前使用$表示被匯編時(shí)將使用相應(yīng)的值替代$后的符號(hào)。

macroname 所定義的宏的名稱。

$parameter 宏指令的參數(shù)。當(dāng)宏指令被展開時(shí)將被替換成相應(yīng)的值,類似于函數(shù)中的形式參數(shù)。

對(duì)于子程序代碼比較短,而需要傳遞的參數(shù)比較多的情況下可以使用匯編技術(shù)。首先要用MACR 和MEND 偽指令定義宏,包括宏定義體代碼。在MACRO 偽指令之后的第一行聲明宏的原型,其中包含該宏定義的名稱,及需要的參數(shù)。在匯編程序中可以通過(guò)該宏定義的名稱來(lái)調(diào)用它。當(dāng)源程序被匯編時(shí),匯編編譯器將展開每個(gè)宏調(diào)用,用宏定義體代替源程序中的宏定義的名稱,并用實(shí)際的參數(shù)值代替宏定義時(shí)的形式參數(shù)。

偽指令應(yīng)用舉例如下:

MACRO

CSI_SETB ;宏名為CSI_SETB,無(wú)參數(shù)

LDR R0,=rPDATG ;讀取GPG0 口的值

LDR R1,[R0]

ORR R1,R1#0x01 ;CSI 置位操作

STR R1,[R0] ;輸出控制

MEND

帶參數(shù)的宏定義如程序清單:

MACRO

$IRQ_Label HANDLER $IRQ_Exception

EXPORT $IRQ_Label

IMPORT $IRQ_Exception

$IRQ_Label

SUB LR,LR,#4

STMFD SP!,{R0-R3,R12,LR}

MRS R3,STSR

STMFD SP!,{R3}

MEND

WHILE 和WENDWHILE 和WEND 偽指令用于根據(jù)條件重復(fù)匯編相同的或幾乎相同的一段源程序。

偽指令格式:

WHILE logical_expr

;指令或偽指令代碼段

WEND

其中:logical_expr 用于控制的邏輯表達(dá)式。若條件成立,則代碼段在匯編源程序中有效,并不斷重復(fù)這段代碼直到條件不成立。

偽指令應(yīng)用舉例如下:

WHILE no<5

no SETA no+1

WEND

WHILE 和WEND 偽指令是可以嵌套使用的。

A.4.5  雜項(xiàng)偽指令

雜項(xiàng)偽指令在匯編編程設(shè)計(jì)較為常用,如段定義偽指令,入口點(diǎn)設(shè)置偽指令,包含文件偽指令,標(biāo)號(hào)導(dǎo)出或引入聲明等,該類偽指令如下:

邊界對(duì)齊: ALIGN。

段定義: AREA。

指令集定義: CODE16 和CODE32。

匯編結(jié)束: END。

程序入口: ENTRY。

常量定義: EQU。

聲明一個(gè)符號(hào)可以被其它文件引用:EXPORT 和GLORBAL。

聲明一個(gè)外部符號(hào):IMPORT 和EXTERN。

包含文件:GET 和INCLUDE。

包含不被匯編的文件:INCBIN。

保留符號(hào)表中的局部符號(hào):KEEP。

禁止浮點(diǎn)指令:NOFP。

指示兩段之間的依賴關(guān)系:REQUIRE。

堆棧8 字節(jié)對(duì)齊:PEQUIRE8 和PRESERVE8。

給特定的寄存器命名:RN。

標(biāo)記局部標(biāo)號(hào)使用范圍的界限:ROUT。

ALIGN------         ALIGN 偽指令通過(guò)添加補(bǔ)丁字節(jié)使當(dāng)前位置滿足一定的對(duì)齊方式。         偽指令格式:

ALIGN {expr{,offset}}

其中:expr 數(shù)字表達(dá)式,用于指定對(duì)齊的方式。取值為2 的n 次冪,如1、2、4、8等,不能為0 其沒(méi)有expr,則默認(rèn)為字對(duì)齊方式。

offset 數(shù)字表達(dá)式,當(dāng)前位置對(duì)齊到下面形式的地址處:offset+n*expr

在下面的情況中,需要特定的地址對(duì)齊方式:

(A)Thumb 偽指令A(yù)DR 要求地址是字對(duì)齊的。而Thumb 代碼中地址標(biāo)號(hào)可能不是字對(duì)齊的。這時(shí)就要使用偽指令A(yù)LIGN4 使Thumb 代碼中地址標(biāo)號(hào)為字對(duì)齊。

(B)由于有些ARM 處理器的Cache 采用了其他對(duì)齊方式。如16 字節(jié)對(duì)齊方式,這時(shí)使用ALIGN 偽指令指定合適的對(duì)齊方式可以充分發(fā)揮Cache 的性能優(yōu)勢(shì)。

(C)LDRD 和STRD 指令要求存儲(chǔ)單元為8 字節(jié)對(duì)齊。這樣在為L(zhǎng)DRD/STRD 指令分配的存儲(chǔ)單元前要使用偽指令A(yù)LIGN8 實(shí)現(xiàn)8 字節(jié)對(duì)齊方式。

(D)地址標(biāo)號(hào)通常自身沒(méi)有對(duì)齊要求,而在ARM 代碼中要求地起標(biāo)號(hào)對(duì)齊是字對(duì)齊的,Thumb 代碼中要求半字對(duì)齊。這樣可以使用ALIGN4 和ALIGN2 偽指令來(lái)調(diào)整對(duì)齊方式。

偽指令應(yīng)用舉例如下。

通過(guò)ALIGN 偽指令使程序中的地址標(biāo)號(hào)字對(duì)齊:

AREA Example,CODE,READONLY ;聲明代碼段Example

START LDR R0,=Sdfjk

MOV PC,LR

Sdfjk DCB 0x58 ;定義一字節(jié)存儲(chǔ)空間,字對(duì)齊方式被破壞

ALIGN ;聲明字對(duì)齊

SUBI MOV R1,R3 ;其它代碼

MOV PC,LR

在段定義AREA 中,也可使用ALIGN 偽指令對(duì)齊,但表達(dá)式的數(shù)字含義是同的

AREA MyStack,DATA,NOINIT,ALIGN=2 ;聲明數(shù)據(jù)段

;MyStack,并重新字對(duì)齊

IrqStackSpace SPACE IRQ_STACK_LEGTH*4 ;中斷模式堆棧空間

FiqStackSpace SPACE FIQ_STACK_LEGTH*4 ;快速中斷模式堆??臻g

AbtStackSpace SPACE ABT_STACK_LEGTH*4 ;中止義模式堆??臻g

UndtStackSpace SPACE UND_STACK_LEGTH*4 ;未定義模式堆棧

將兩個(gè)字節(jié)的數(shù)據(jù)放在同一個(gè)字的第一個(gè)字節(jié)和第四個(gè)字節(jié)中,帶offset 的ALIGN對(duì)齊:

AREA offsetFxample, CODE

DCB 0x31 ;第一個(gè)字節(jié)保存0x31

ALIGN 4,3 ;字對(duì)齊

DCB 0x32 ;第四個(gè)字節(jié)保存0x32

AREAAREA 偽指令用于定義一個(gè)代碼段或數(shù)據(jù)段。ARM 匯編程序設(shè)計(jì)采用分段式設(shè)計(jì),一個(gè)ARM 源程序至少需要一個(gè)代碼段,大的程序可以包含多少個(gè)代碼段及數(shù)據(jù)段。

偽指令格式:

AREA sectionname{,attr}{,attr}…

其中:sectionname 所定義的代碼段或數(shù)據(jù)段的名稱。如果該名稱是以數(shù)據(jù)開頭的,則該名稱必須用“|”括起來(lái),如|1_datasec|。還有一些代碼段具有的約定的名稱。如|text|表示C 語(yǔ)言編譯器產(chǎn)生的代碼段或者與C 語(yǔ)言庫(kù)相關(guān)的代碼段。

attr 該代碼段或數(shù)據(jù)段的屬性。

在AREA 偽指令中,各屬性之間用逗號(hào)隔開。以下為段屬性及相關(guān)說(shuō)明:

ALIGN = expr。默認(rèn)的情況下,ELF 的代碼段和數(shù)據(jù)段是4 字節(jié)對(duì)齊的,expr 可以取0~31 的數(shù)值,相應(yīng)的對(duì)齊方為2expr 字節(jié)對(duì)齊。如expr=3 時(shí)為字節(jié)對(duì)齊。對(duì)于代碼段,expr 不能為0 或1。

ASSOC = section。指定與本段相關(guān)的ELF 段。任何時(shí)候連接section 段也必須包括sectionname 段。

DODE 為定義代碼段。默認(rèn)屬性為READONLY。

COMDEF 定義一個(gè)通用的段。該段可以包含代碼或者數(shù)據(jù)。在其它源文件中,同名的COMDEF 段必須相同。

COMMON 定義一個(gè)通用的段。該段不包含任何用戶代碼和數(shù)據(jù),連接器將其初始化為此。各源文件中同名的COMMON 段共用同樣的內(nèi)存單元,連接器為其分配合適的尺寸。

DATA 為定義段。默認(rèn)屬性為READWRITE。

NOINIT 指定本數(shù)據(jù)段僅僅保留了內(nèi)存單元,而沒(méi)有將各初始寫入內(nèi)存單元,或者將內(nèi)存單元值初始化為0。

READONLY 指定本段為只讀,代碼段的默認(rèn)屬性為READONLY。

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

使用AREA 偽指令將程序分為多個(gè)ELF 格式的段,段名稱可以相同, 這時(shí)同名的段被放在同一個(gè)ELF 段中。

偽指令應(yīng)用舉例如下:

AREA Example ,CODE,READNOLY ;聲明一個(gè)代碼,名為Example

CODE16 和CODE32CODE16 偽指令指示匯編編譯器后面的指令為16 位的Thumb 指令。  CODE32 偽指令指示匯編編譯器后面的指令為32 位的ARM 指令。

偽指令格式:

CODE16

CODE32

CODE16 和CODE32 偽指令只是指示匯編編譯器后面的指令的類型,偽指令本身并不進(jìn)行程序狀態(tài)的切換。要進(jìn)行狀態(tài)切換,可以使用BX 指令操作。

偽指令應(yīng)用舉例如下:

AREA Example CODE,READONLY

CODE32

使用CODE16 和CODE32 定義Thumb 指令及ARM 指令并用BX 指令進(jìn)行切換。

CODE16 和CODE32 的使用:

AREA ArmThumC,CODE,READONLY

CODE32

ADR R0,ThumbStart+1

BX R0

CODE16

ThumbStart

MOV R0,#10

END

ENDEND 偽指令用于指示匯編編譯器源文件已結(jié)束。每一個(gè)匯編源文件均要使用一個(gè)END 偽指令,指示本源程序結(jié)束。

偽指令格式:

END

ENTRYENTRY 偽指令用于指定程序的入口點(diǎn)。

偽指令格式:

ENTRY

一個(gè)程序(可以包含多個(gè)源文件)中至少要有一個(gè)ENTRY,可以有多個(gè)ENTRY。但一個(gè)源文件中最多只有一個(gè)ENTRY。

偽指令應(yīng)用舉例如下。

AREA, Example, CODE,READNOLY

ENTRY

CODE32

START MOV R1,#0x5F

EQUEQU 偽指令為數(shù)字常量,基于寄存器的值和程序中的標(biāo)號(hào)定義一個(gè)名稱。*與EQU同義。

指令格式:

name EQU expr{,type}

其中:name 要定義的常量的名稱。

expr 基于寄存器的地址值,程序中的標(biāo)號(hào),32 位地址常量或32 位常量。

type 當(dāng)expr 為32 位常量時(shí),可用type 指示expr 表示的數(shù)據(jù)類型。如下示例:

CODE16

CODE32

DATA

EQU 偽指令的作用類似于C 語(yǔ)言中的#define。用于為一個(gè)常量定義名稱。

偽指令應(yīng)用舉例如下:

T_bit EQU 0x20 ;定義常量T_bit,其值為0x20

PLLCON EQU 0xE01FC080 ;定義寄存器PLLCON,地址為0Xe01F080

ABCD EQU label+8 ;定義ABCD 為label+8

EXPORT 和GLOBALEXPORT 聲明一個(gè)符號(hào)可以被其它文件引用。相當(dāng)于聲明了一個(gè)全局變量。  GLOBAL 與EXPORT 相同

指令格式:

EXPORT symbol{[WEAK]}

GLOBAL symbol{[WEAK]}

其中:symbol 要聲明的符號(hào)名稱

[WEAK] 聲明其它的同名符優(yōu)先于本符號(hào)被引用。

偽指令應(yīng)用舉例如下:

EXPORT InitStack

GLOBAL Vectors

IMPORT 和EXTERNIMJPORT 偽指令指示編譯器當(dāng)前的符號(hào)不是在本源文件中定義的,而是在其他源文件中定義的,在本源文件中可能引用該符號(hào)。

EXTERN 與IMPORT 相同

指令格式:

IMPORT symbol{[WEAK]}

EXTERN symbol{[WEAK]}

其中:symbol 要聲明的符號(hào)名稱。

[WEAK] 指定該選項(xiàng)后,如果symbol 在所有的源程序中都沒(méi)有被定義,編譯器也不會(huì)生任何錯(cuò)誤信息,同時(shí)編譯器也不會(huì)到當(dāng)前沒(méi)有被INCLUDE 進(jìn)來(lái)庫(kù)中去查找該標(biāo)號(hào)。

使用IMPORT 或EXTERN 聲明外部標(biāo)號(hào)時(shí),若連接器在連接處理時(shí)不能解釋該符號(hào),而偽指令中沒(méi)有[WEAK]選項(xiàng),則連接器會(huì)報(bào)告錯(cuò)誤,若偽指令中有[WEAK]選項(xiàng),則連接器不會(huì)報(bào)告錯(cuò)誤,而是進(jìn)行下面的操作:

(A)如果該符號(hào)被B 或者BL 指令引用,則該符號(hào)被設(shè)置成下一條指令的地址,該B 或者BL 指令相當(dāng)于一條NOP 指令。

(B)其它情況下該符號(hào)被設(shè)置0。

偽指令應(yīng)用舉例如下:

IMPORT InitStack

EXTERN Vectors

GET 和INCLUDEGET 偽指令將一個(gè)源文件包含到當(dāng)前源文件中,并將被包含的文件在當(dāng)前位置進(jìn)行匯編處理。INCLUDE 與GFT 同義。

指令格式:

GET filename

INCLUDE filename

其中:filename 要包含的源文件名,可以使用路徑信息。

GET 偽指令通常用于包含一些宏定義或常量定義的源文件。如用EQU 定義的常量,用MAP 和FIELD 定義的結(jié)構(gòu)化的數(shù)據(jù)類型,這樣的源文件類似于C 語(yǔ)言中的頭文件,GET、INCLUDE 偽指令不能用來(lái)包含目標(biāo)文件,而INCBIN 偽指令可以包含目標(biāo)文件。

偽指令應(yīng)用舉例如下:

INCLUDE LPC2106.inc

INCBININCBIN 偽指令將一個(gè)文件包含到當(dāng)前源文件中,而被包含的文件不進(jìn)行匯編處理。

指令格式:

INCBIN filename

其中:filename 要包含的源文件名,可以使用路徑信息。

通??梢允褂肐NCBIN 將一個(gè)執(zhí)行文件或者任意數(shù)據(jù)包含到當(dāng)前文件中,被包含的執(zhí)行文件或數(shù)據(jù)將被原封不動(dòng)地放下當(dāng)前文件中,編譯器從INCBIN 偽指令后面開始繼續(xù)處理。

偽指令應(yīng)用舉例如下:

NCBIN charlib。bin

KEEPKEEP 偽指令指示編譯器保留符號(hào)表中的局部符號(hào)。

偽指令格式:

KEEP {symbol}

其中:symbol 要保留的局部標(biāo)號(hào)。若沒(méi)有此項(xiàng),則除了基于寄存器處的所有符號(hào)將包含在目標(biāo)文件的符號(hào)表中。

NOFPNOFP 偽指令用于禁止源程序中包含浮點(diǎn)運(yùn)算指令。

偽指令格式:

NOFP

REQUIREREQUIRE 偽指令指定段之間的依賴關(guān)系。

偽指令格式:

REQUIRE label

其中:label 所需要的標(biāo)號(hào)的名稱。

當(dāng)進(jìn)行鏈接處理時(shí),包含了REQUIRE label 偽指令的源文件,則定義label 的源文件也被包含。

PEQUIRE8 和PRESERVE8PEQUIRE8 偽指令指示當(dāng)前文件請(qǐng)求堆棧為8 字節(jié)對(duì)齊。

PRESERVE8 偽指令指示當(dāng)前文件保持堆棧為8 字節(jié)對(duì)齊。

偽指令格式:

PEQUIRE8

PRESERVE8

鏈接器保證要求8 字節(jié)對(duì)齊的堆棧只能被堆棧為8 字的對(duì)齊的代碼調(diào)用

轉(zhuǎn)載出處:ARM匯編偽指令

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多

    男生和女生哪个更好色| 国产三级欧美三级日韩三级| 国产原创激情一区二区三区| 国产成人精品视频一二区| 国产不卡在线免费观看视频| 国产又粗又猛又爽又黄的文字| 日本精品理论在线观看| 亚洲中文字幕人妻系列| 91国内视频一区二区三区| 精品人妻av区波多野结依| 国产成人精品资源在线观看| 欧美自拍偷自拍亚洲精品| 欧美日本精品视频在线观看| 中日韩美女黄色一级片| 欧美日韩人妻中文一区二区| 国产一区二区三区丝袜不卡| 亚洲高清一区二区高清| 大香蕉久久精品一区二区字幕| 老司机精品国产在线视频| 厕所偷拍一区二区三区视频| 亚洲专区一区中文字幕| 99久久国产亚洲综合精品| 狠狠做五月深爱婷婷综合| 99国产精品国产精品九九| 国产成人精品一区二区三区| 九九九热视频免费观看| 精品香蕉一区二区在线| 国产亚洲中文日韩欧美综合网 | 日本熟妇熟女久久综合| 亚洲国产日韩欧美三级| 精品一区二区三区三级视频| 欧美在线观看视频免费不卡| 亚洲一级二级三级精品| 99亚洲综合精品成人网色播| 成年人免费看国产视频| 成人国产一区二区三区精品麻豆| 尹人大香蕉一级片免费看| 人妻内射在线二区一区| 丝袜av一区二区三区四区五区 | 中文字幕欧美精品人妻一区| 成人你懂的在线免费视频|