版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第1頁!主講內(nèi)容第1章嵌入式系統(tǒng)概述第2章ARM微處理器概述與編程模型第3章ARM9指令系統(tǒng)第4章嵌入式程序設(shè)計基礎(chǔ)第5章嵌入式內(nèi)部可編程模塊第6章嵌入式接口技術(shù)應(yīng)用第7章軟件開發(fā)環(huán)境嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第2頁!第4章嵌入式程序設(shè)計基礎(chǔ)
基于ARM的編譯器一般都支持匯編語言的程序設(shè)計、C/C++語言的程序設(shè)計及兩者的混合編程。本章介紹ARM的嵌入式程序的基礎(chǔ)知識偽指令匯編語言的語句格式匯編語言C/C++語言的混合編程……..嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第3頁!4.1偽指令在ARM匯編語言程序里,有一些特殊指令助記符,這些助記符與指令系統(tǒng)的助記符不同,沒有相對應(yīng)的操作碼,通常稱這些特殊指令助記符為偽指令,他們所完成的操作稱為偽操作。偽指令在源程序中的作用是既要把正常的程序用指令表達(dá)給計算機(jī)以外,又要把程序設(shè)計者的意圖表達(dá)給編譯器.
例如:要告訴編譯器程序段的開始和結(jié)束,需要定義數(shù)據(jù)等.嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第4頁!4.1.1通用偽指令
通用偽指令包括:符號定義偽指令數(shù)據(jù)定義偽指令匯編控制偽指令及其他一些常用偽指令等。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第5頁!4.1.1通用偽指令
其中:GBLA用于聲明一個全局的數(shù)字變量,并初始化為0;GBLL偽指令用于聲明一個全局的邏輯變量,并初始化為F(假);GBLS偽指令用于聲明一個全局的字符串變量,并初始化為空;對于全局變量來說,變量名在源程序中必須是唯一的。1.符號定義偽指令符號定義偽指令用于聲明ARM匯編程序中的變量、對變量賦值以及定義寄存器的名稱等操作。常見的符號定義偽指令有如下幾種:(1)GBLA、GBLL和GBLS嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第6頁!4.1.1通用偽指令
(2)LCLA、LCLL和LCLS語法格式:
LCLA(LCLL或LCLS) 局部變量名
LCLA、LCLL和LCLS偽指令是聲明局部變量偽指令,用于定義一個ARM程序中的局部變量,并將其初始化。其中:LCLA用于聲明一個局部的數(shù)字變量,并初始化為0;LCLL用于聲明一個局部的邏輯變量,并初始化為F(假);LCLS用于聲明一個局部的字符串變量,并初始化為空。對于局部變量來說,變量名在使用的范圍內(nèi)必須是唯一的,范圍限制在定義這個變量的宏指令程序段內(nèi)。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第7頁!4.1.1通用偽指令
(3)SETA、SETL和SETS語法格式: 變量名SETA(SETL或SETS)表達(dá)式
SETA、SETL、SETS是變量賦值偽指令,用于給一個已經(jīng)定義的全局變量或局部變量賦值。其中:SETA用于給一個數(shù)學(xué)變量賦值;SETL用于給一個邏輯變量賦值;SETS用于給一個字符串變量賦值;嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第8頁!4.1.1通用偽指令
(4)RLIST語法格式:名稱RLIST{寄存器列表}RLIST偽指令是定義通用寄存列表偽指令,通用寄存器列表定義主要應(yīng)用在堆棧操作或多寄存器傳送中,即使用該偽指令定義的名稱可在ARM指令LDM/STM中使用。在LDM/STM指令中,列表中的寄存器訪問次序為根據(jù)寄存器的編號由低到高,而與列表中的寄存器排列次序無關(guān)。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第9頁!4.1.1通用偽指令
2.數(shù)據(jù)定義偽指令數(shù)據(jù)定義偽指令一般用于為特定的數(shù)據(jù)分配存儲單元,同時可完成已分配存儲單元的初始化。常見的數(shù)據(jù)定義偽指令有如下幾種:(1)DCB語法格式:標(biāo)號DCB 表達(dá)式
DCB偽指令是字節(jié)分配內(nèi)存單元偽指令,用來分配一片連續(xù)的字節(jié)存儲單元并用偽指令中指定的數(shù)值或字符初始化。其中,數(shù)值范圍為0~255,DCB也可用“=”代替。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第10頁!4.1.1通用偽指令
(2)DCW(或DCWU)語法格式:標(biāo)號 DCW(或DCWU)表達(dá)式
DCW(或DCWU)偽指令是為半字分配內(nèi)存單元,其中,表達(dá)式可以為程序標(biāo)號或數(shù)字表達(dá)式。偽指令DCW用于為半字分配一段半字對準(zhǔn)的內(nèi)存單元,并用指定的數(shù)據(jù)初始化;偽指令DCWU用于為半字分配一段可以非半字對準(zhǔn)的內(nèi)存單元,并用指定的數(shù)據(jù)初始化。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第11頁!4.1.1通用偽指令
(3)DCD(或DCDU)語法格式:標(biāo)號DCD(或DCDU) 表達(dá)式
DCD(或DCDU)偽指令是為字分配內(nèi)存單元偽指令,其中,表達(dá)式可以為程序標(biāo)號或數(shù)字表達(dá)式。DCD也可用“&”代替。偽指令DCD用來為字分配一段對準(zhǔn)的內(nèi)存單元,并用指定的數(shù)值或標(biāo)號初始化;偽指令DCDU用來為字分配一段可以非對準(zhǔn)的內(nèi)存單元,并用指定的數(shù)值或標(biāo)號初始化。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第12頁!4.1.1通用偽指令
(4)DCFD(或DCFDU)和DCFS(或DCFSU)語法格式:標(biāo)號偽指令表達(dá)式DCFD(或DCFDU)和DCFS(或DCFSU)都是為浮點數(shù)分配內(nèi)存單元的偽指令。DCFD用于為雙精度的浮點數(shù)分配一段字對準(zhǔn)的內(nèi)存單元,并用指定的數(shù)據(jù)初始化,每個雙精度的浮點數(shù)占兩個字單元;DCFDU用于為雙精度的浮點數(shù)分配一段非字對準(zhǔn)的內(nèi)存單元,并用指定的數(shù)據(jù)初始化,每個雙精度的浮點數(shù)占兩個字單元;DCFS用于為單精度的浮點數(shù)分配一段字對準(zhǔn)的內(nèi)存單元,并用指定的數(shù)據(jù)初始化,每個單精度的浮點數(shù)占一個字單元;DCFSU用于為單精度的浮點數(shù)分配一段非字對準(zhǔn)的內(nèi)存單元,并用指定的數(shù)據(jù)初始化,每個單精度的浮點數(shù)占一個字單元。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第13頁!4.1.1通用偽指令
(5)DCQ(或DCQU)語法格式:標(biāo)號DCQ(或DCQU)表達(dá)式
DCQ(或DCQU)偽指令是為雙字分配內(nèi)存單元的偽指令。偽指令DCQ用于為雙字分配一段字對準(zhǔn)的內(nèi)存單元,并用指定的數(shù)據(jù)初始化;偽指令DCQU用于為雙字分配一段可以非字對準(zhǔn)的內(nèi)存單元,并用指定的數(shù)據(jù)初始化。指令示例:
DATA1 DCQ 100
;分配一片連續(xù)的存儲單元并初始化為指定的值。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第14頁!4.1.1通用偽指令
表達(dá)式可以為程序中的標(biāo)號或數(shù)學(xué)表達(dá)式,基址寄存器為可選項,當(dāng)基址寄存器選項不存在時,表達(dá)式的值即為內(nèi)存表的首地址,當(dāng)該選項存在時,內(nèi)存表的首地址為表達(dá)式的值與基址寄存器的和。注意MAP和FIELD偽指令僅用于定義數(shù)據(jù)結(jié)構(gòu),并不實際分配存儲單元。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第15頁!4.1.1通用偽指令
(7)SPACE語法格式:標(biāo)號 SPACE分配的內(nèi)存單元字節(jié)數(shù)
SPACE偽指令是內(nèi)存單元分配偽指令,用于分配一片連續(xù)的存儲區(qū)域并初始化為0,SPACE也可用“%”代替。指令示例:
DATASPASPACE 100 ;為DATASPA分配100個存儲單元;并初始化為0嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第16頁!4.1.1通用偽指令
偽指令MACRO定義一個宏語句段的開始;偽指令MEND定義宏語句段的結(jié)束;偽指令MEXIT可以實現(xiàn)從宏程序段的跳出。宏指令可以使用一個或多個參數(shù),當(dāng)宏指令被展開時,這些參數(shù)被相應(yīng)的值替換。MACRO、MEND偽指令可以嵌套使用。宏是一段功能完整的程序,能夠?qū)崿F(xiàn)一個特定的功能,在使用中可以把它視為一個子程序。在其他程序中,可以調(diào)用宏完成某個功能。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第17頁!4.1.1通用偽指令
指令示例:MACRO ;定義宏$DATA1MAX$N1,$N2 ;宏名稱是MAX,主標(biāo)號是$DATA1,兩個參數(shù)語句段 ;語句段
$DATA1.MAY1 ;非主標(biāo)號,由主標(biāo)號構(gòu)成語句段 ;語句段…… $DATA1.MAY2 ;非主標(biāo)號,由主標(biāo)號構(gòu)成……MEND ;宏結(jié)束嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第18頁!4.1.1通用偽指令
指令示例:IF R0=0x10
;判斷R0中的內(nèi)容是否是0x10ADD R0,R1,R2
;如果R0=0x10,則執(zhí)行R0=R1+R2
ELSEADD R0,R1,R3
;如果R0≠0x10,則執(zhí)行R0=R1+R3ENDIF嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第19頁!4.1.1通用偽指令
指令示例:GBLA Cou1 ;聲明一個全局的數(shù)學(xué)變量,變量名為CounterCou1 SETA 1 ;為Cou1賦值1WHILECou1<10 ;判斷WHILE Counter<10進(jìn)入循環(huán)
ADDR1,R2,R3 ;循環(huán)執(zhí)行語句Cou1SETACou1+1 ;每次循環(huán)Cou1加1WEND ;執(zhí)行ADDR1,R2,R3語句10次后,結(jié)束循環(huán)。
在應(yīng)用WHILE、WEND偽指令時要注意:用來進(jìn)行條件判斷的邏輯表達(dá)式必須是編譯程序能夠判斷的語句,一般應(yīng)該是偽指令語句。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第20頁!4.1.1通用偽指令
指令示例:BSTARTADDR0,R1,R2 ;正常語句DATA1DCB“Ertai” ;由于插入5個字節(jié)的存儲區(qū),地址不對準(zhǔn)ALIGN4 ;使用偽指令確保地址對準(zhǔn)STARTLDRR5,[R6] ;否則此標(biāo)號不對準(zhǔn)
……嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第21頁!4.1.1通用偽指令
AREA常用的屬性如下:①CODE屬性:用于定義代碼段,默認(rèn)為READONLY。②DATA屬性:用于定義數(shù)據(jù)段,默認(rèn)為READWRITE。③READONLY屬性:指定本段為只讀,代碼段默認(rèn)為READONLY。④READWRITE屬性:指定本段為可讀可寫,數(shù)據(jù)段的默認(rèn)屬性為READWRITE。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第22頁!4.1.1通用偽指令
指令示例:AREA Example1,CODE,READONLY;定義了一個代碼段,段名為Example1,屬性為只讀。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第23頁!4.1.1通用偽指令
指令示例:AREA Example1,CODE,READONLY……CODE32 ;定義后面的指令為32位的ARM指令LDR R0,=NEXT+1;將跳轉(zhuǎn)地址放入寄存器R0BX R0 ;程序跳轉(zhuǎn)到新的位置執(zhí)行,并將處理器切換到Thumb工作狀態(tài)……CODE16 ;定義后面的指令為16位的Thumb指令NEXT LDR R3,=0x3FF ……END ;程序結(jié)束嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第24頁!4.1.1通用偽指令
(5)END語法格式:ENDEND偽指令是編譯結(jié)束偽指令,用于通知編譯器已經(jīng)到了源程序的結(jié)尾,每個匯編語言的源程序都必須有一個END偽指令定義源程序結(jié)尾。編譯程序檢測到這個偽指令后,不再對后面的程序編譯。指令示例:AREA Example1,CODE,READONLY……END ;程序結(jié)束嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第25頁!4.1.1通用偽指令
指令示例:Test EQU 50 ;定義標(biāo)號Test的值為50DATA1EQU0x55,CODE32 ;定義DATA1的值為0x55且該處為32位的ARM指令嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第26頁!4.1.1通用偽指令
指令示例:AREAExample1,CODE,READONLYGET File1.s ;包含文件File1.s,并編譯INCBINFile2.dat ;包含文件File2.s,不編譯……GET F:\EX\File3.s
;包含文件File3.s,并編譯……END 嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第27頁!4.1.2與ARM指令相關(guān)的偽指令
1.ADR偽指令語法格式:ADR{cond}
Rd,語句標(biāo)號+數(shù)值表達(dá)式;其中Rd是目標(biāo)寄存器,為R0~R15。
ADR偽指令是把地址加載到寄存器中的偽指令,這個地址可以是基于PC相對偏移的地址值,也可以是基于寄存器相對偏移的地址值讀取到寄存器中。對偏移的地址值限定的范圍是:字對準(zhǔn)時,不得超過±1020B;非字對準(zhǔn)時,不得超過±255B。 指令示例:
ADRR1,LOOP
;把LOOP處絕對地址加載給R1
ADRR1,LOOP+0x10
;把LOOP+0x10處絕對地址加載給R1嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第28頁!4.1.2與ARM指令相關(guān)的偽指令
3.LDR偽指令語法格式:LDR{cond}
Rd,=數(shù)值表達(dá)式 ;加載數(shù)字常量LDR{cond}
Rd,=語句標(biāo)號+數(shù)值表達(dá)式;加載地址LDR偽指令是把一個數(shù)字常量或一個地址加載到寄存器偽指令。LDR偽指令主要用于以下兩個目的:一是用于MOV和MVN指令中,若立即數(shù)由于超出范圍而不能加載到寄存器中時,產(chǎn)生文字常量;另一個是將程序相對偏移量或一個標(biāo)號所對應(yīng)的地址加載到寄存器中。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第29頁!4.1.2與ARM指令相關(guān)的偽指令
4.NOP語法格式:NOPNOP偽指令是空操作指令,在匯編時將被編譯成一條無效指令,如MOVR0,R0,占用32位代碼空間。NOP偽指令不影響CPSR中的條件標(biāo)志位。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第30頁!4.1.3與Thumb指令相關(guān)的偽指令
與Thumb指令相關(guān)的偽指令共有3條,這些偽指令必須出現(xiàn)在Thumb程序段。ADR偽指令LDR偽指令NOP嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第31頁!4.1.3與Thumb指令相關(guān)的偽指令
指令示例:
ADRR0,LOOP
;把LOOP處絕對地址;加載給R0 ADRR1,LOOP+0x40*2
;把LOOP+0x40*2處;絕對地址加載給R1……
ALIGNLOOPADDR2,R0,R1……嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第32頁!4.1.3與Thumb指令相關(guān)的偽指令
在使用LDR指令替代偽指令時,編譯程序先把數(shù)據(jù)(或地址)存放在數(shù)據(jù)緩沖區(qū)內(nèi),在執(zhí)行LDR指令時,從緩沖區(qū)讀出這個數(shù)據(jù)加載到寄存器中去。因此,在使用這條偽指令時,要為程序創(chuàng)建數(shù)據(jù)緩沖區(qū)。指令示例:LDRR1,=0xFFE ;加載0xFFE到R1中 ;匯編器匯編成MOVR1,#0xFFELDRR1,=START ;加載START處的地址到R1中嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第33頁!4.2匯編語言的語句格式
匯編語言的源程序主要組成:指令偽指令語句標(biāo)號注釋嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第34頁!4.2.1書寫格式
舉例:AREAEXAMPLE1,CODE,READONLY ;EXAMPLE1程序段代碼段,只讀屬性嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第35頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
(1)數(shù)字變量用于在程序的運(yùn)行中保存數(shù)字值,數(shù)字變量的取值范圍不能超過一個32位數(shù)所能表達(dá)的范圍。全局?jǐn)?shù)字變量使用偽指令GBLA定義;局部數(shù)字變量使用偽指令LCLA定義;數(shù)字變量使用偽指令SETA賦值。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第36頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
(3)字符串變量用于在程序的運(yùn)行中保存一個字符串.全局串變量使用偽指令GBLS定義;局部串變量使用偽指令LCLS定義;串變量使用偽指令SETS賦值。
串變量需要使用雙引號包含。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第37頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
指令示例:LCLS String1
;定義局部字符串變量String1和String2LCLS String2 String1SETS“pen!”String2SETS“Thisisa$String1”;字符串變量S2的值為“ThisisaTest!”嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第38頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
若是十進(jìn)制,在表達(dá)的時候可以直接表達(dá),例如:1234、56789。若是十六進(jìn)制,有兩種表達(dá)方法。一種是在數(shù)值前加“0x”另一種是在數(shù)值前加“&”。例如:0x12A,&FF00。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第39頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
若是ASCII表達(dá):有些值可以使用ASCII表達(dá)。例如:‘A’表達(dá)A的ASCII碼。例如:MOVR1,#′A′等同于MOVR1,#0x41。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第40頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
(4)數(shù)字運(yùn)算符是表明兩個表達(dá)式之間的關(guān)系。在數(shù)字表達(dá)式中,操作符有以下幾種:①算術(shù)運(yùn)算符“+”加“-”減“×”乘“/”除“MOD”取余數(shù)嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第41頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
②移位運(yùn)算符“ROL”、“ROR”、“SHL”及“SHR”以A和B表示兩個數(shù)字表達(dá)式,以上的移位運(yùn)算符代表的運(yùn)算如下:
A:ROL:B 表示將A循環(huán)左移B位。
A:ROR:B 表示將A循環(huán)右移B位。
A:SHL:B 表示將A左移B位。
A:SHR:B 表示將A右移B位。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第42頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
3.邏輯表達(dá)式及運(yùn)算符邏輯表達(dá)式包括邏輯值、邏輯變量、邏輯操作符、關(guān)系操作符和括號構(gòu)成,其表達(dá)式的運(yùn)算結(jié)果為真或假。與邏輯表達(dá)式相關(guān)的運(yùn)算符如下:(1)邏輯值:只有{TRUE}或{FALSE}。(2)邏輯變量:可以用偽指令定義邏輯變量。(3)邏輯運(yùn)算符:包括“LAND”、“LOR”、“LNOT”及“LEOR”運(yùn)算符,他們在運(yùn)算時優(yōu)先權(quán)較低。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第43頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
(4)關(guān)系運(yùn)算符:關(guān)系運(yùn)算符所關(guān)聯(lián)的兩個操作數(shù)必須形式相同,運(yùn)算結(jié)果應(yīng)該是一個邏輯值。包括“=”、“>”、“<”、“>=”、“<=”、“/=”、“<>”
運(yùn)算符。
以A和B表示兩個邏輯表達(dá)式,以上的運(yùn)算符代表的運(yùn)算如下:
A=B 表示A等于B。
A>B 表示A大于B。
A<B 表示A小于B。
A>=B 表示A大于等于B。
A<=B 表示A小于等于B。
A/=B 表示A不等于B。
X<>B 表示A不等于B。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第44頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
4.字符串表達(dá)式及運(yùn)算符字符串表達(dá)式包括字符串常量、字符串變量、運(yùn)算符和括號構(gòu)成。編譯器所支持的字符串最大長度為512字節(jié)。(1)字符串:用雙引號包含在內(nèi)的一系列字符稱為字符串。(2)字符串變量:被定義為變量的字符串稱為字符串變量嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第45頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
單目運(yùn)算符語法格式功能LEN:LEN:X當(dāng)X是一個字符串時,計算X的長度。CHR:CHR:X當(dāng)X是一個0~255之間的數(shù)字時,把X轉(zhuǎn)換成ASCII的字符串。STR:STR:X將32位的數(shù)字表達(dá)式X轉(zhuǎn)換為8個字符的16進(jìn)制字符串,或邏輯表達(dá)式X轉(zhuǎn)換為字符串T或F。DEF:DEF:X如果符號A已經(jīng)定義,則結(jié)果為真,否則為假。表4-1單目運(yùn)算符嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第46頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
指令實例:GBLSSTRING ;定義字符串STRINGSTRING SETS:CHR:65;為STRING賦值 ;(65是A的ASCII)GBLSSTRING2 ;定義字符串STRING2STRING2SETS“EMBEDDEDSYSTEM” ;為STRING2賦值GBLSSTRING3 ;定義字符串STRING3STRING3SETSSTRING2:LEFT:8 ;將值EMBEDDED賦值給字符串STRING3嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第47頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
(2)INDEX運(yùn)算符INDEX運(yùn)算符返回基于寄存器的表達(dá)式中相對于其基址寄存器的偏移量,其語法格式如下: :INDEX:A
其中,A為與寄存器相關(guān)的表達(dá)式。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第48頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
運(yùn)算符優(yōu)先級順序(由高到底)單目運(yùn)算符乘除和取膜(×、/、MOD)移位運(yùn)算(ROL、ROR、SHL、SHR)加減和邏輯運(yùn)算(+、-、AND、OR、EOR)各種邏輯運(yùn)算(=、>、<、>=、<=、/=、<>)邏輯運(yùn)算(LAND、LOR、LEOR)表4-3運(yùn)算符優(yōu)先級嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第49頁!4.3.1匯編程序基本結(jié)構(gòu)
AREA偽指令定義一個段,并說明所定義段的相關(guān)屬性,本例定義一個名為example的代碼段,屬性為只讀。
ENTRY偽指令標(biāo)識程序的入口點,接下來為語句段。執(zhí)行主代碼后,通過返回控制終止應(yīng)用程序并返回到DEBUG,通過使用軟件中斷指令實現(xiàn)了返回。在程序的末尾為END偽指令,該偽指令通知編譯器停止對源文件的處理,每一個匯編程序段都必須有一條END偽指令,指示代碼段的結(jié)束。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第50頁!4.3.2子程序調(diào)用
習(xí)慣上用寄存器R0~R3來存放送到子程序的參數(shù),然后從子程序返回時存放返回的結(jié)果給調(diào)用者。下面給出的子程序,減4個參數(shù)的值,用R0返回結(jié)果(即實現(xiàn)R0=R0-R1-R2-R3)。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第51頁!4.4匯編語言與C/C++的混合編程
在應(yīng)用系統(tǒng)的程序設(shè)計中,若所有的編程任務(wù)均用匯編語言來完成,其工作量是可想而知的。事實上,ARM體系結(jié)構(gòu)支持C/C+以及與匯編語言的混合編程,在一個完整的程序設(shè)計的中,除了初始化部分用匯編語言完成以外,其主要的編程任務(wù)一般都用C/C++完成。匯編語言與C/C++的混合編程通常有以下幾種方式:在C/C++代碼中嵌入?yún)R編指令。在匯編程序和C/C++的程序之間進(jìn)行變量的互訪。匯編程序、C/C++程序間的相互調(diào)用。 嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第52頁!4.4匯編語言與C/C++的混合編程
PCS強(qiáng)制實現(xiàn)如下約定:調(diào)用函數(shù)如何傳遞參數(shù)(即壓棧方法,以何種方式存放參數(shù)),被調(diào)用函數(shù)如何獲取參數(shù),以何種方式傳遞函數(shù)返回值。PCS的制訂是一系列指標(biāo)的“tradeoff(折衷)”(因為很大程度上涉及系統(tǒng)的一些性能),如:會涉及生成代碼的大小,調(diào)試功能的支持,函數(shù)調(diào)用上下文處理速度以及內(nèi)存消耗等。當(dāng)然,通過編譯器的支持可以讓生成的代碼有不同的特性,如:gcc編譯選項可以支持或不支持framepointer來支持深入調(diào)試功能或提高程序運(yùn)行性能。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第53頁!4.4匯編語言與C/C++的混合編程
1.各寄存器的使用規(guī)則(1)子程序通過寄存器R0~R3來傳遞參數(shù)。這時寄存器可以記作:A0~A3,被調(diào)用的子程序在返回前無需恢復(fù)寄存器R0~R3的內(nèi)容。(2)在子程序中,使用R4~R11來保存局部變量,這時寄存器R4~R11可以記作:V1~V8。如果在子程序中使用到V1~V8的某些寄存器,子程序進(jìn)入時必須保存這些寄存器的值,在返回前必須恢復(fù)這些寄存器的值,對于子程序中沒有用到的寄存器則不必執(zhí)行這些操作。在THUMB程序中,通常只能使用寄存器R4~R7來保存局部變量。(3)寄存器R12用作子程序間scratch寄存器,記作ip;在子程序的連接代碼段中經(jīng)常會有這種使用規(guī)則。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第54頁!4.4匯編語言與C/C++的混合編程
2.數(shù)據(jù)棧的使用規(guī)則
ATPCS規(guī)定數(shù)據(jù)棧為滿遞減類型。并對數(shù)據(jù)棧的操作是8字節(jié)對齊的,下面是一個數(shù)據(jù)棧的示例及相關(guān)的名詞。(1)數(shù)據(jù)棧棧指針(stackpointer),其指向最后一個寫入棧的數(shù)據(jù)的內(nèi)存地址。(2)數(shù)據(jù)棧的基地址(stackbase),是指數(shù)據(jù)棧的最高地址。由于ATPCS中的數(shù)據(jù)棧是FD類型的,實際上數(shù)據(jù)棧中最早入棧數(shù)據(jù)占據(jù)的內(nèi)存單元是基地址的下一個內(nèi)存單元。
嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第55頁!4.4匯編語言與C/C++的混合編程
3.參數(shù)的傳遞規(guī)則根據(jù)參數(shù)個數(shù)是否固定,可以將子程序分為參數(shù)個數(shù)固定的子程序和參數(shù)個數(shù)可變的子程序。
(1)參數(shù)個數(shù)可變的子程序參數(shù)傳遞規(guī)則對于參數(shù)個數(shù)可變的子程序,當(dāng)參數(shù)不超過4個時,可以使用寄存器R0~R3來進(jìn)行參數(shù)傳遞,當(dāng)參數(shù)超過4個時,還可以使用數(shù)據(jù)棧來傳遞參數(shù)。在參數(shù)傳遞時,將所有參數(shù)看做是存放在連續(xù)的內(nèi)存單元中的字?jǐn)?shù)據(jù)。然后,依次將各名字?jǐn)?shù)據(jù)傳送到寄存器R0、R1、R2、R3;如果參數(shù)多于4個,將剩余的字?jǐn)?shù)據(jù)傳送到數(shù)據(jù)棧中,入棧的順序與參數(shù)順序相反,即最后一個字?jǐn)?shù)據(jù)先入棧。按照上面的規(guī)則,一個浮點數(shù)參數(shù)可以通過寄存器傳遞,也可以通過數(shù)據(jù)棧傳遞,也可能一半通過寄存器傳遞,另一半通過數(shù)據(jù)棧傳遞。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第56頁!4.4匯編語言與C/C++的混合編程
4.子程序結(jié)果返回規(guī)則
(1)結(jié)果為一個32位的整數(shù)時,可以通過寄存器R0返回。
(2)結(jié)果為一個64位整數(shù)時,可以通過R0和R1返回,依此類推。
(3)對于位數(shù)更多的結(jié)果,需要通過調(diào)用內(nèi)存來傳遞。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第57頁!4.4.1在C/C++程序中內(nèi)嵌匯編指令的語法格式
在ARMC語言程序中使用關(guān)鍵字_asm來標(biāo)識一段匯編指令程序,其用法如下:
__asm{instruction[;instruction]匯編語言程序段以及注釋
… [instruction]}其中,如果一行中有多個匯編指令,指令之間使用分號“;”隔開;如果一條指令占多行,使用續(xù)行符號”\”表示接續(xù);在匯編指令段中可以使用C語言的注釋語句。在ARMC/C++程序中還可以使用關(guān)鍵詞asm來內(nèi)嵌一段匯編程序,其格式如下:asm(“instruction[;instruction]”);其中,asm后面括號中必須是一條匯編語句,且其不能包含注釋語句。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第58頁!4.4.2C/C++與匯編語言的混合編程應(yīng)用
(4)一般不要直接指定物理寄存器,而讓編譯器進(jìn)行分配。下面通過一個例子來說明如何在C中內(nèi)嵌匯編語言:#include<stdio.h>voidmy_strcpy(constchar*src,char*dest) //聲明一個函數(shù){ charch; //聲明一個字符型變量
__asm //調(diào)用關(guān)鍵詞__asm { LOOP ;循環(huán)入口
LDRBCH,[SRC],#1 ;Thumb指令,ch←src+1.將無符;號src地址的數(shù)+1送入ch STRBCH,[dest],#1 ;Thumb指令,[dest+1]←ch,;將無符號CH數(shù)據(jù)送入[dest+1]存儲
CMPCH,#0 ;比較CH是否為零,否則循環(huán)。;總共循環(huán)256次
BNELOOP; ;B指令跳轉(zhuǎn),NE為Z位清零不相等
}}嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第59頁!4.4.2C/C++與匯編語言的混合編程應(yīng)用
2.在匯編中使用C程序全局變量內(nèi)嵌匯編不用單獨(dú)編輯匯編語言文件,比較簡潔,但是有諸多限制,當(dāng)匯編的代碼較多時一般放在單獨(dú)的匯編文件中。這時就需要在匯編和C之間進(jìn)行一些數(shù)據(jù)的傳遞,最簡便的辦法就是使用全局變量。具體的匯編程序中訪問方法如下:(1)使用IMPORT偽操作聲明該全局變量。(2)使用LDR指令讀取該全局變量的內(nèi)存地址,通常該全局變量的內(nèi)存地址值存放在程序的數(shù)據(jù)緩沖池中(Literalpool)。(3)根據(jù)該數(shù)據(jù)的類型,使用相應(yīng)的LDR/STR指令讀取/修改該全局變量的值。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第60頁!4.4.2C/C++與匯編語言的混合編程應(yīng)用
3.C程序中調(diào)用匯編的函數(shù)在C程序中調(diào)用匯編文件中的函數(shù),主要工作有兩個:一是在C中聲明函數(shù)原型,并加extern關(guān)鍵字;二是在匯編中用EXPORT導(dǎo)出函數(shù)名,并用該函數(shù)名作為匯編代碼段的標(biāo)識,最后用MOVPC,LR返回。然后,就可以在C程序中使用該函數(shù)了。下面是一個C程序調(diào)用匯編程序的例子,其中匯編程序strcpy實現(xiàn)字符串復(fù)制功能,C程序調(diào)用strcpy完成字符串復(fù)制的工作。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第61頁!4.4.2C/C++與匯編語言的混合編程應(yīng)用
;匯編語言程序段AREAasmfile,CODE,READONLY;聲明匯編語言程序段EXPORTasm_strcpy ;聲明可被調(diào)用函數(shù)名稱asm_strcpy ;函數(shù)入口地址LOOP ;循環(huán)標(biāo)志條LDRBR4,[R0],#1 ;R0的地址加1后送給R4CMPR4,#0 ;比較R4是否為零BEQOVER ;為零跳轉(zhuǎn)到結(jié)束STRBR4,[R1],#1 ;R4的值送入R1加1地址BLOOP ;跳轉(zhuǎn)到循環(huán)位置OVER ;跳出標(biāo)志位MOVPC,LR ;子函數(shù)返回END嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第62頁!4.4.2C/C++與匯編語言的混合編程應(yīng)用
EXPORTasmfile ;可被調(diào)用的匯編段AREAasmfile,CODE,READONLY;聲明匯編程序段IMPORTcFun ;聲明調(diào)用C語言的cFun函數(shù)ENTRY ;主程序起始入口MOVR0,#11 ;將11放入R0MOVR1,#22 ;將22放入R1MOVR2,#33 ;將33放入R2BLcFun;調(diào)用C語言子函數(shù)END/*C語言函數(shù),被匯編語言調(diào)用*/intcFun(inta,intb,intc)//聲明一個函數(shù){ returna+b+c;//返回a+b+c的值}嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第63頁!4.4.2C/C++與匯編語言的混合編程應(yīng)用
例如:externinta;此語句僅僅是在聲明一個變量,并不是定義變量a,并未為a分配內(nèi)存空間。變量a在所有模塊中作為一種全局變量只能被定義一次,否則會出現(xiàn)連接錯誤。通常,在模塊的頭文件中對模塊提供給其他模塊引用的函數(shù)和全局變量以關(guān)鍵字extern聲明。例如,如果模塊B欲引用該模塊A中定義的全局變量和函數(shù)時只需包含模塊A的頭文件即可。這樣,模塊B中調(diào)用模塊A中的函數(shù)時,在編譯階段,模塊B雖然找不到該函數(shù),但是并不會報錯,它會在連接階段中從模塊A編譯生成的目標(biāo)代碼中找到此函數(shù)。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第64頁!4.4.2C/C++與匯編語言的混合編程應(yīng)用
該函數(shù)被C編譯器編譯后在符號庫中的名字為_foo,而C++編譯器則會產(chǎn)生像_foo_int_int之類的名字(不同的編譯器可能產(chǎn)生的名字不同,但是都采用了相同的機(jī)制)。_foo_int_int這樣的名字包含了函數(shù)名、函數(shù)參數(shù)數(shù)量及類型信息,C++就是靠這種機(jī)制來實現(xiàn)函數(shù)重載的。例如,在C++中,函數(shù)voidfoo(intx,inty)與voidfoo(intx,floaty)編譯產(chǎn)生的符號是不相同的,后者為_foo_int_float。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第65頁!4.4.2C/C++與匯編語言的混合編程應(yīng)用
而在C語言的頭文件中,對其外部函數(shù)只能指定為extern類型,C語言中不支持extern"C"聲明,在.c文件中包含了extern"C"時會出現(xiàn)編譯語法錯誤。②在C中引用C++語言中的函數(shù)和變量時,C++的頭文件需添加extern"C",但是在C語言中不能直接引用聲明了extern"C"的頭文件,應(yīng)該僅將C文件中將C++中定義的extern"C"函數(shù)聲明為extern類型。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第66頁!4.4.2C/C++與匯編語言的混合編程應(yīng)用
/*C實現(xiàn)文件cFile.c/*這樣會編譯出錯:#include"cppExample.h"*/externintadd(intx,inty);intmain(intargc,char*argv[])//C語言主程序入口{
add(2,3);
return0;}嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第67頁!在ARM的匯編程序中,我們把偽指令分為三部分介紹:通用偽指令與ARM指令相關(guān)的偽指令與Thumb指令相關(guān)的偽指令
4.1偽指令嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第68頁!4.1.1通用偽指令
1.符號定義偽指令符號定義偽指令用于聲明ARM匯編程序中的變量、對變量賦值以及定義寄存器的名稱等操作。常見的符號定義偽指令有如下幾種:(1)GBLA、GBLL和GBLS語法格式:
GBLA(GBLL或GBLS) 全局變量名
GBLA、GBLL和GBLS偽指令是聲明全局變量的偽指令,用于定義一個ARM程序中的全局變量,并將其初始化。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第69頁!4.1.1通用偽指令
指令示例:
GBLA DATE1
;聲明一個全局?jǐn)?shù)字變量DATE1
GBLL DATE1
;聲明一個全局邏輯變量DATE2
GBLS DATA3
;聲明一個全局的字符串變量DATE3
DATE3 SETS“Testing”
;將該變量賦值為“Testing”嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第70頁!4.1.1通用偽指令
指令示例:
LCLA DATE4
;聲明一個局部數(shù)字變量DATE4
LCLL DATE5
;聲明一個局部的邏輯變量DATE5
DATA4 SETL0x10
;為變量DATE4賦值為0x10
LCLS DATA6
;聲明一個局部的字符串變量DATA6嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第71頁!4.1.1通用偽指令
指令示例:
GBLAEXAMP1;先聲明一個全局?jǐn)?shù)字變量EXAMP1EXAMP1SETA 0xaa
;將變量EXAMP1賦值為0xaa
LCLLEXAMP2;聲明一個局部的邏輯變量EXAMP2
EXAMP1SETL {TRUE};將變量EXAMP1賦值為TRUE
GBLAEXAMP3
;先聲明一個全局字符串變量EXAMP3 EXAMP3SETS “string”;將變量EXAMP3賦值為string嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第72頁!4.1.1通用偽指令
指令示例:RegList RLIST {R0-R5,R8}
;定義寄存器列表為RegList在程序中使用:STMFDSP!,RegList
;存儲列表到堆棧LDMIAR5,RegList
;加載列表嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第73頁!4.1.1通用偽指令
指令示例:StringDCB“Thisisatest!”
;分配一片連續(xù)的字節(jié)存儲單元并初始化。DATA2DCB15,25,62,00
;為數(shù)字常量15,25,62,00分片內(nèi)存單元嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第74頁!4.1.1通用偽指令
指令示例:DATA1DCW1,2,3;分配一片連續(xù)的半字存儲單元并初始化為1,2,3。DATA2DCWU45,0x2a*0x2a
;分配一片非半字對準(zhǔn)存儲單元并初始化。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第75頁!4.1.1通用偽指令
指令示例:DATA1DCD 4,5,6 ;分配一片連續(xù)的字存儲單元并初始化。DATA2DCDULOOP;為LOOP標(biāo)號的地址值分配一個內(nèi)存單元。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第76頁!4.1.1通用偽指令
指令示例:FLO1DCFD 2E115,-5E7
;分配一段字對準(zhǔn)存儲單元并初始化為指定的雙精度數(shù)為2E115,-5E7。FLO2DCFDU 22,1E2
;分配一段非字對準(zhǔn)存儲單元并初始化為指定的雙精度數(shù)為22,1E2。FLO3DCFS 2E5,-5E-7
;分配一段非字對準(zhǔn)存儲單元并初始化為指定的單精度數(shù)為2E5,-5E-7。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第77頁!4.1.1通用偽指令
(6)MAP和FILED語法格式:MAP 表達(dá)式,{基址寄存器}
標(biāo)號FIELD表明數(shù)據(jù)字節(jié)數(shù)的數(shù)值MAP和FILED是內(nèi)存表定義偽指令。偽指令MAP用于定義一個結(jié)構(gòu)化的內(nèi)存表的首地址,MAP也可用“^”代替;偽指令FIELD用于定義內(nèi)存表中的數(shù)據(jù)的長度。FILED也可用“#”代替。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第78頁!4.1.1通用偽指令
指令示例:MAP 0x10,R1
;定義內(nèi)存表首地址的值為[R1]+0x10。DATA1 FIELD 4
;為數(shù)據(jù)DATA1定義4字節(jié)長度DATA2 FIELD 16
;為數(shù)據(jù)DATA1定義16字節(jié)長度嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第79頁!4.1.1通用偽指令
3.匯編控制偽指令匯編控制偽指令用于控制匯編程序的執(zhí)行流程,常用的匯編控制偽指令包括以下幾條:(1)MACRO、MEND和MEXIT語法格式:MACRO$標(biāo)號 宏名 $參數(shù)1,$參數(shù)2,…… 語句段MEXIT語句段MENDMACRO、MEND和MEXIT都是宏定義指令。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第80頁!4.1.1通用偽指令
調(diào)用宏是通過調(diào)用宏的名稱來實現(xiàn)的。宏指令的使用方式和功能與子程序有些相似,子程序可以提供模塊化的程序設(shè)計、節(jié)省存儲空間并提高運(yùn)行速度。但在使用子程序結(jié)構(gòu)時需要保護(hù)現(xiàn)場,從而增加了系統(tǒng)的開銷,因此,在代碼較短且需要傳遞的參數(shù)較多時,可以使用宏指令代替子程序。調(diào)用宏的好處是不占用傳送參數(shù)的寄存器,不用保護(hù)現(xiàn)場。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第81頁!4.1.1通用偽指令
(2)IF、ELSE、ENDIF語法格式:IF邏輯表達(dá)式 語句段1ELSE
語句段2ENDIFIF、ELSE、ENDIF偽指令是條件分支偽指令,能根據(jù)條件的成立與否決定是否執(zhí)行某個語句。偽指令I(lǐng)F可以對條件進(jìn)行判斷;偽指令ELSE產(chǎn)生分支;偽指令ENDIF定義分支結(jié)束。當(dāng)IF后面的邏輯表達(dá)式為真,則執(zhí)行語句段1,否則執(zhí)行語句段2。其中,ELSE及語句段2可以沒有,此時,當(dāng)IF后面的邏輯表達(dá)式為真,則執(zhí)行指令序列1,否則繼續(xù)執(zhí)行后面的指令。IF、ELSE、ENDIF偽指令可以嵌套使用。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第82頁!4.1.1通用偽指令
(3)WHILE、WEND語法格式:WHILE 邏輯表達(dá)式 語句段WENDWHILE、WEND偽指令是條件循環(huán)偽指令,能根據(jù)條件的成立與否決定是否循環(huán)執(zhí)行某個語句段。偽指令WHILE對條件進(jìn)行判斷,滿足條件循環(huán),不滿足條件結(jié)束循環(huán);偽指令WEND定義循環(huán)體結(jié)束。當(dāng)WHILE后面的邏輯表達(dá)式為真,則執(zhí)行語句段,該語句段執(zhí)行完畢后,再判斷邏輯表達(dá)式的值,若為真則繼續(xù)執(zhí)行,一直到邏輯表達(dá)式的值為假。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第83頁!4.1.1通用偽指令
4.其他雜類偽指令下面是一些比較重要的雜類偽指令,這些雜類偽指令在匯編程序中經(jīng)常會被使用,包括以下幾條:(1)ALIGN語法格式:ALIGN {表達(dá)式{,偏移量}} ALIGN偽指令是地址對準(zhǔn)偽指令,可通過插入字節(jié)使存儲區(qū)滿足所要求的地址對準(zhǔn)。其中,表達(dá)式的值用于指定對準(zhǔn)方式,可能的取值為2n,0≤n≤31,如果不選表達(dá)式,則默認(rèn)字對準(zhǔn);偏移量也為一個數(shù)字表達(dá)式,若使用該字段,則當(dāng)前位置的對齊方式為:2n+偏移量。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第84頁!4.1.1通用偽指令
(2)AREA語法格式:AREA 段名 屬性1,屬性2,…… AREA偽指令是段指示偽指令,用于定義一個代碼段或數(shù)據(jù)段。其中,段名若以數(shù)字開頭,則該段名需用“|”括起來,如|1_test|。屬性字段表示該代碼段(或數(shù)據(jù)段)的相關(guān)屬性,多個屬性用逗號分隔。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第85頁!4.1.1通用偽指令
AREA常用的屬性如下:⑤ALIGN屬性:使用方式為ALIGN表達(dá)式。在默認(rèn)時,ELF(可執(zhí)行連接文件)的代碼段和數(shù)據(jù)段是按字對齊的,表達(dá)式的取值范圍為0~31,相應(yīng)的對齊方式為2表達(dá)式次方。⑥COMMON屬性:該屬性定義一個通用的段,不包含任何的用戶代碼和數(shù)據(jù)。各源文件中同名的COMMON段共享同一段存儲單元。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第86頁!4.1.1通用偽指令
(3)CODE16、CODE32語法格式:CODE16CODE32CODE16和CODE32偽指令是代碼長度定義偽指令。若在匯編源程序中同時包含ARM指令和Thumb指令時,可用CODE16偽指令定義后面的代碼編譯成16位的Thumb指令,CODE32偽指令定義后面的代碼編譯成32位的ARM指令。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第87頁!4.1.1通用偽指令
(4)ENTRY語法格式:ENTRYENTRY偽指令是程序入口偽指令。在一個完整的匯編程序中至少要有一個ENTRY,編譯程序在編譯連接時依據(jù)程序入口進(jìn)行連接。在只有一個入口時,編譯程序會把這個入口的地址定義為系統(tǒng)復(fù)位后的程序起始點。但在一個源文件里最多只能有一個ENTRY。指令示例:AREAExample1,CODE,READONLYENTRY ;程序的入口處……嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第88頁!4.1.1通用偽指令
(6)EQU語法格式:名稱EQU 表達(dá)式{,類型}EQU偽指令是賦值偽指令,用于為程序中的常量、標(biāo)號等定義一個等效的字符名稱。
名稱為EQU偽指令定義的字符名稱,當(dāng)表達(dá)式為32位的常量時,可以指定表達(dá)式的數(shù)據(jù)類型,可以有以下三種類型:CODE16、CODE32和DATA。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第89頁!4.1.1通用偽指令
(7)GET和INCBIN語法格式: GET 文件名 INCBIN文件名GET和INCBIN偽指令是文件引用偽指令。偽指令GET聲明包含另一個源文件,并將被包含的源文件在當(dāng)前位置進(jìn)行匯編處理;偽指令I(lǐng)NCBIN聲明包含另一個源文件,在INCBIN處引用這個文件但不匯編。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第90頁!4.1.2與ARM指令相關(guān)的偽指令
與ARM指令相關(guān)的偽指令共有4條。這4條偽指令和通用偽指令不同,在程序編譯過程中,編譯程序會為這4條指令產(chǎn)生代碼,但這些代碼不是它們自己的代碼,所以盡管它們可以產(chǎn)生代碼,但還是偽指令。ADR偽指令A(yù)DRL偽指令LDR偽指令NOP嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第91頁!4.1.2與ARM指令相關(guān)的偽指令
2.ADRL偽指令語法格式:ADR{cond}
Rd,語句標(biāo)號+數(shù)值表達(dá)式;其中Rd是目標(biāo)寄存器,為R0~R15。ADRL偽指令是把長地址加載到寄存器中的偽指令,這個地址可以是基于PC相對偏移的地址值,也可以是基于寄存器相對偏移的地址值讀取到寄存器中。對偏移的地址值限定的范圍是:字對準(zhǔn)時,不得超過±256K;非字對準(zhǔn)時,不得超過±64K。指令示例:ADRLR1,0x10
;把距離程序開始處16個地址單元處的絕對地址加載給R1。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第92頁!4.1.2與ARM指令相關(guān)的偽指令
指令示例:LDRR1,=0x20
;加載0x20到R1中;匯編器匯編成MOVR1,#0x20LDRR1,=0x101
;加載0x101到R1中;匯編器匯編成LDRR1,[PC,offsect_data1] data1DCD0x101嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第93頁!4.1.2與ARM指令相關(guān)的偽指令
指令示例:ADDRES1LDRR1,=ADDRES2
;把ADDRES2地址加載給R1 ADRR2,ADDRES1
;把ADDRES1地址加載給R2 SUBR3,R1,R2
;相減
…… ADDRES2NOP
;空操作嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第94頁!4.1.3與Thumb指令相關(guān)的偽指令
1.ADR偽指令語法格式:ADR{cond}
Rd,語句標(biāo)號+數(shù)值表達(dá)式;其中Rd是目標(biāo)寄存器,為R0~R7。
ADR偽指令是把地址加載到低端寄存器中的偽指令,這個地址必須是基于PC相對偏移的地址值。偏移必須向前偏移,偏移量不大于1KB,且該指令只可以加載字對準(zhǔn)的地址。
嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第95頁!4.1.3與Thumb指令相關(guān)的偽指令
2.LDR偽指令語法格式:LDR{cond}
Rd,=數(shù)值表達(dá)式 ;加載數(shù)字常量LDR{cond}
Rd,=語句標(biāo)號+數(shù)值表達(dá)式;加載地址LDR偽指令是把一個數(shù)字常量或一個地址加載到低端寄存器偽指令。如果所加載的是一個32位的數(shù)字常量,則編譯程序就可以把這條語句編譯成一條MOV指令,如果不能用MOV指令來表達(dá),則編譯成一條LDR指令。如果所加載的是地址的話,編譯程序會把這條語句編譯成LDR指令。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第96頁!4.1.3與Thumb指令相關(guān)的偽指令
3.NOP語法格式: NOP NOP偽指令是空操作指令,在匯編時將被編譯成一條無效指令,如MOVR0,R0,占用32位代碼空間。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第97頁!4.2.1書寫格式
ARM(Thumb)匯編語言的語句格式為: {語句標(biāo)號}{指令或偽指令}{;注釋}1.語句標(biāo)號語句標(biāo)號可以大小寫字母混合使用,可以使用數(shù)字和下劃線。語句標(biāo)號不能與指令助記符、寄存器、變量名同名。2.指令和偽指令指令助記符和偽指令助記符可以大寫,也可以小寫,但不能大小寫混合使用。指令助記符和后面的操作數(shù)寄存器之間必須有空格,不可以在這之間使用逗號。3.注釋匯編器在編譯時,當(dāng)發(fā)現(xiàn)一個分號后,把后面的內(nèi)容解釋為注釋,不予以編譯。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第98頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
在匯編語言程序設(shè)計中,經(jīng)常使用各種符號代替地址、變量和常量等,以增加程序的可讀性。1.變量 ARM(Thumb)匯編程序所支持的變量形式有3種:數(shù)字變量邏輯變量字符串變量變量在編譯過程中可能被改變。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第99頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
(2)邏輯變量用于在程序的運(yùn)行中保存邏輯值,邏輯值只有兩種取值情況:真或假。全局邏輯變量使用偽指令GBLL定義;局部邏輯變量使用偽指令LCLL定義;邏輯變量使用偽指令SETA賦值。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第100頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
(4)變量代換
程序中的變量可通過代換操作取得一個常量。
代換操作符為“$”。如果在數(shù)字變量前面有一個代換操作符“$”,編譯器會將該數(shù)字變量的值轉(zhuǎn)換為十六進(jìn)制的字符串,并將該十六進(jìn)制的字符串代換“$”后的數(shù)字變量;如果在邏輯變量前面有一個代換操作符“$”,編譯器會將該邏輯變量代換為它的取值(真或假);如果在字符串變量前面有一個代換操作符“$”,編譯器會將該字符串變量的值代換“$”后的字符串變量。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第101頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
2.數(shù)字表達(dá)式及運(yùn)算符
數(shù)字表達(dá)式包括數(shù)字、數(shù)字常量、數(shù)字變量、數(shù)字運(yùn)算符和括號構(gòu)成。表達(dá)式的結(jié)果不能超過一個32位數(shù)的表達(dá)范圍。(1)數(shù)字形式可以:十進(jìn)制十六進(jìn)制N進(jìn)制ASCII嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第102頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
若是N進(jìn)制:N是一個2~9之間的整數(shù)。表示方法是n_數(shù)值。例如: 2_01101111是一個二進(jìn)制數(shù)字 8_54231067是一個八進(jìn)制數(shù)字。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第103頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
(2)數(shù)字常量是一個32位的整數(shù)。
可以使用偽指令EQU定義一個數(shù)字常量,并且定義后不能改變。(3)數(shù)字變量是被定義變量的數(shù)字。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第104頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
以A和B表示兩個數(shù)字表達(dá)式為例:A+B 表示A與B的和。A-B 表示A與B的差。A×B 表示A與B的乘積。A/B 表示A除以B的商。A:MOD:B 表示A除以B的余數(shù)。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第105頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
③邏輯運(yùn)算符“AND”、“OR”、“NOT”及“EOR”以A和B表示兩個數(shù)字表達(dá)式,以上的按位邏輯運(yùn)算符代表的運(yùn)算如下:A:AND:B 表示將A和B按位作邏輯與的操作。A:OR:B 表示將A和B按位作邏輯或的操作。A:EOR:B 表示將A和B按位作邏輯異或的操作。NOT:B 表示將B按位作邏輯非的操作。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第106頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
以A和B表示兩個邏輯表達(dá)式,以上的邏輯運(yùn)算符代表的運(yùn)算如下:
A:LAND:B 表示將A和B作邏輯與的操作。
A:LOR:B 表示將A和B作邏輯或的操作。
A:LEOR:B 表示將A和B作邏輯異或的操作。
LNOT:B 表示將B作邏輯非的操作。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第107頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
指令示例:
MOVR5,#0xFF00:MOD:0xF:ROL:2 ;R5寄存器里的內(nèi)容為0x00 IFR5:LAND:R6<=R7 MOVR0,#0x00 ELSE MOVR0,#0xFF;如果R5∧R6<=R7則R0=0x00
;否則,R0=0xFF嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第108頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
(3)單目運(yùn)算符:是只涉及一個字符串的運(yùn)算符,在串運(yùn)算中,單目運(yùn)算符有較高的優(yōu)先權(quán)。
單目運(yùn)算符如表4-1所示。(4)雙目運(yùn)算符:涉及兩個表達(dá)式,其中至少有一個是字符串。
雙目運(yùn)算符如表4-2所示。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第109頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
雙目運(yùn)算符語法格式功能LEFTX:LEFT:Y從字符串X中左側(cè)取字符Y個。RIGHTX:RIGHT:Y從字符串X中右側(cè)取字符Y個。CCX:CC:Y將字符串Y接在字符串X后面形成一個字符串表4-2雙目運(yùn)算符嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第110頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
5.以寄存器和程序計數(shù)器(PC)為基址的表達(dá)式及運(yùn)算符常用的與寄存器和程序計數(shù)器(PC)相關(guān)的表達(dá)式及運(yùn)算符如下:(1)BASE運(yùn)算符BASE運(yùn)算符返回基于寄存器的表達(dá)式中寄存器的編號,其語法格式如下: :BASE:A
其中,A為與寄存器相關(guān)的表達(dá)式。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第111頁!4.2.2匯編語言中表達(dá)式和運(yùn)算符
6.運(yùn)算符的優(yōu)先級在對匯編程序進(jìn)行編譯時,運(yùn)算中一般遵循的基本規(guī)則是:先計算括號內(nèi),后計算括號外;在有多個操作符時,順序和運(yùn)算符有關(guān);單目運(yùn)算符較雙目運(yùn)算符優(yōu)先;在相同優(yōu)先權(quán)情況下,從左到右運(yùn)算。
運(yùn)算符的優(yōu)先級如表4-3所示。嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是第112頁!4.3匯編程序應(yīng)用
4.3.1匯編程序基本結(jié)構(gòu)下面是一個匯編語言源程序的基本結(jié)構(gòu):AREAexample,CODE,READONLY;定義代碼塊為exampleENTRY ;程序入口Start MOVR0,#40 ;R0=40MOVR1,#16 ;R1=16ADDR2,R0,R1 ;R2=R0+R1MOVR0,#0x18 ;傳送到軟件中斷的參數(shù)LDRR1,=0x20026 ;傳送到軟件中斷的參數(shù)SWI0x123456 ;通過軟件中斷指令返回END ;文件結(jié)束嵌入式系統(tǒng)原理及應(yīng)用教程第4章共131頁,您現(xiàn)在瀏覽的是
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 全新網(wǎng)絡(luò)游戲開發(fā)合同2篇
- 2024-2025學(xué)年新教材高中歷史第八單元20世紀(jì)下半葉世界的新變化第19課資本主義國家的新變化課時作業(yè)含解析新人教版必修中外歷史綱要下
- 2025不動產(chǎn)登記信息化改造項目合同3篇
- 2025年微信小程序企業(yè)客戶關(guān)系管理系統(tǒng)開發(fā)與應(yīng)用合同3篇
- 2024銷售人員職業(yè)發(fā)展保障勞動合同3篇
- 二零二五年度醫(yī)療設(shè)施臨時借款合同參考樣本4篇
- 2025高溫粘合劑產(chǎn)業(yè)鏈金融服務(wù)平臺合作合同3篇
- 2025年度電信設(shè)備知識產(chǎn)權(quán)保護(hù)合同3篇
- 2025年度食品行業(yè)退換貨質(zhì)量保證協(xié)議書
- 二零二五年度高層建筑樓頂廣告位使用權(quán)租賃合同3篇
- 臺資企業(yè)A股上市相關(guān)資料
- 電 梯 工 程 預(yù) 算 書
- 羅盤超高清圖
- 參會嘉賓簽到表
- 機(jī)械車間員工績效考核表
- 形式發(fā)票格式2 INVOICE
- 2.48低危胸痛患者后繼治療評估流程圖
- 人力資源管理之績效考核 一、什么是績效 所謂績效簡單的講就是對
- 山東省醫(yī)院目錄
- 云南地方本科高校部分基礎(chǔ)研究
- 廢品管理流程圖
評論
0/150
提交評論