第4節(jié)匯編語言源程序格式_第1頁
第4節(jié)匯編語言源程序格式_第2頁
第4節(jié)匯編語言源程序格式_第3頁
第4節(jié)匯編語言源程序格式_第4頁
已閱讀5頁,還剩21頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡介

1、第 4 節(jié) 匯編語言源程序格式第 4 章 匯編語言程序設(shè)計(jì)匯編語言源程序格式匯編語言上機(jī)過程匯編語言與C 語言混合編程技術(shù)常用 ARM 源程序文件類型匯編語言程序的結(jié)構(gòu)1匯編語言程序的結(jié)構(gòu)2匯編語言程序的結(jié)構(gòu)3匯編語言程序的結(jié)構(gòu)4ARM 的匯編語言程序一般由幾個(gè)段組成,每個(gè)段均由AREA 偽操作定義。段可以分為多種,如代碼段、數(shù)據(jù)段、通用段,每個(gè)段又有不同的屬性,如代碼段的默認(rèn)屬性為 READONLY,數(shù)據(jù)段的默認(rèn)屬性為READWRITE 。本程序定義了兩個(gè)段,第一個(gè)段為代碼段codesec ,它在存儲(chǔ)器中存放用于程序執(zhí)行的代碼以及 main 函數(shù)的本地字符串;第二個(gè)段為數(shù)據(jù)段constdat

2、asec ,存放了全局的字符串,由于本程序沒有對(duì)數(shù)據(jù)進(jìn)行寫操作,該數(shù)據(jù)段定義屬性為READONLY。匯編語言的行構(gòu)成1格式:標(biāo)簽 指令 /偽操作 /偽指令操作數(shù); 語句的注釋所有的標(biāo)簽必須在一行的開頭頂格寫,前面不能留空格,后面也不能跟樣加上 “:;”ARM 匯編器對(duì)標(biāo)識(shí)符的大小寫敏感,書寫標(biāo)號(hào)及指令時(shí)字母的大小寫要一致;注釋使用 “;符”號(hào),注釋的內(nèi)容從“;開”始到該行的結(jié)尾結(jié)束C 語言中的標(biāo)簽一匯編語言的行構(gòu)成2標(biāo)簽標(biāo)簽是一個(gè)符號(hào),可以代表指令的地址、變量、數(shù)據(jù)的地址和常量。一般以字母開頭,由字母、數(shù)字、下劃線組成。當(dāng)符號(hào)代表地址時(shí)又稱標(biāo)號(hào),可以以數(shù)字開頭,其作用范圍為當(dāng)前段或者在下一個(gè)R

3、OUT偽操作之前。指令 / 偽操作指令 / 偽操作是指令的助記符或者定義符, 它告訴 ARM 的處理器應(yīng)該執(zhí)行什么樣的操作或者告訴匯編程序偽指令語句的偽操作功能。匯編語言的標(biāo)號(hào)1標(biāo)號(hào)代表地址。標(biāo)號(hào)分為段內(nèi)標(biāo)號(hào)和段外標(biāo)號(hào)。 段內(nèi)標(biāo)號(hào)的地址值在匯編時(shí)確定, 段外編號(hào)的地址值在鏈接時(shí)確定 。在程序段中,標(biāo)號(hào)代表其所在位置與段首地址的偏移量。根據(jù)程序計(jì)數(shù)器(PC)和偏移量計(jì)算地址即程序相對(duì)尋址。在映像中定義的標(biāo)號(hào)代表標(biāo)號(hào)到映像首地址的偏移量。映像的首地址通常被賦予一個(gè)寄存器,根據(jù)該寄存器值與偏移量計(jì)算地址即寄存器相對(duì)尋址。例如:loop SUBS r0,r0,#1 ;每次循環(huán)使r0=r0-1BNE l

4、oop ; 跳轉(zhuǎn)到 loop標(biāo)號(hào)去執(zhí)行匯編語言的標(biāo)號(hào)2在宏中也可以使用局部符號(hào)。局部標(biāo)號(hào)是099 的十進(jìn)位數(shù)開始,可以重復(fù)定義。局部標(biāo)號(hào)引用格式: F|BA|T Nroutname % :局部標(biāo)號(hào)引用操作。F :編譯器只向前搜索。B :編譯器只向后搜索。A :編譯器搜索宏的所有嵌套層次。T :編譯器搜索宏的當(dāng)前層。例如:01 SUBS r0,r0,#1 ;每次循環(huán)使r0=r0-1BNE %B01 ; 跳轉(zhuǎn)到 01 標(biāo)號(hào)去執(zhí)行匯編語言的常量常量:其值在程序運(yùn)行過程中不能被改變的量。( 1 )數(shù)字常量:數(shù)字常量有 3 種表示方式:十進(jìn)制數(shù),如 1 、2 、 123十六進(jìn)制數(shù),如0x123,0xab

5、cn 進(jìn)制數(shù),形式為n_XXX, n 的范圍是2 到 9 ,XXX 是具體數(shù)字(2 )字符常量:由單引號(hào)及中間的字符組成,包括C 語言中的轉(zhuǎn)義字符,如an,(3 )字符串常量:由一對(duì)雙引號(hào)及中間的字符串表示,中間也可以使用C 語言中的轉(zhuǎn)義字符,比如: “abcdefn”( 4 )邏輯常量: TRUE,FALSE, 注意帶大括號(hào)匯編程序的變量代換1這里所說的變量,是相對(duì)于匯編程序的 “變量 ”,是用于匯編程序進(jìn)行處理的,但一旦編譯到程序中,則不會(huì)改變,成為常量。在字符串變量的前面有一個(gè) $字符,在匯編時(shí)編譯器將用該字符串變量的內(nèi)容代替該串變量。在數(shù)字變量前面有一個(gè)代換操作符 “$,”編譯器會(huì)將該

6、數(shù)字變量的值轉(zhuǎn)換為十六進(jìn)制的字符串,并用該十六進(jìn)制的字符串代換 “$后”的數(shù)字變量。需要將 “$字”符加入到字符串中,可以用 “$”替,此時(shí)編譯器將不再進(jìn)行變量代換,而是代把“$”看作一個(gè) “$?!痹趦蓚€(gè) “|之”間的 “$并”不進(jìn)行變量的代換,但如果“|在”雙引號(hào)內(nèi),則將進(jìn)行變量代換。使用 “.來”表示字符串中變量名的結(jié)束。匯編程序的變量代換2字符串 “aaa str1:$str1. l1:$l1,a1:$num1.ccc中的” 3個(gè)變量將在編譯時(shí)被替換。程序運(yùn)行后看到下面結(jié)果:aaa str1:bbb l1:T,a1:0000004Fccc偽指令在 ARM 匯編語言源程序中有些特殊助記符,

7、它們沒有相對(duì)應(yīng)的操作碼或者機(jī)器碼,通常稱為偽指令,它們所完成的操作稱為偽操作。偽指令在源程序中的作用是為完成匯編程序作各種準(zhǔn)備工作的, 由匯編程序在源程序的匯編期間進(jìn)行處理,僅在匯編過程中起作用。在 ARM 的匯編程序中,有如下幾種偽指令:符號(hào)定義偽指令數(shù)據(jù)定義偽指令匯編控制偽指令信息報(bào)告?zhèn)沃噶詈曛噶钜约捌渌麄沃噶罘?hào)定義偽指令作用:用于定義ARM 匯編程序中的變量、對(duì)變量賦值以及定義寄存器的別名等。符號(hào)定義有如下幾種偽指令:用于定義局部變量的LCLA、 LCLL 和 LCLS。用于定義全局變量的GBLA、 GBLL 和 GBLS。用于對(duì)變量賦值的SETA、 SETL 和 SETS。為通用寄存

8、器列表定義名稱的RLIST 。符號(hào)定義偽指令1-1( 1 ) LCLA、 LCLL 和 LCLS格式:LCLA/LCLL/LCLS 局部變量名說明: LCLA、 LCLL 和 LCLS 偽指令用于定義一個(gè)匯編程序中的局部變量并初始化。其中:LCLA 定義一個(gè)局部的數(shù)字變量,初始化為0。LCLL 定義一個(gè)局部的邏輯變量,初始化為F。LCLS 定義一個(gè)局部的字符串變量,初始化為空串。這 3 條偽指令用于聲明局部變量,在其局部作用范圍內(nèi)變量名必須惟一,例如在宏內(nèi)。符號(hào)定義偽指令 1-2符號(hào)定義偽指令2-12) GBLA、 GBLL 和 GBLS格式:GBLA/GBLL/GBLS 變量名說明: GBL

9、A、 GBLL 和 GBLS 偽操作定義一個(gè)匯編程序中的全局變量并初始化。其中:GBLA 定義一個(gè)全局?jǐn)?shù)字變量,并初始化為0。GBLL 定義一個(gè)全局邏輯變量,并初始化為F。GBLS 定義一個(gè)全局字符串變量,并初始化為空串。這 3 條偽指令用于定義全局變量,因此在整個(gè)程序范圍內(nèi)變量名必須惟一。符號(hào)定義偽指令2-2例如:GBLA num1 ; 定義一個(gè)全局的數(shù)字變;量,變量名為num1num1 SETA 0xabcd;將該變量賦值為0xabcdGBLL l2 ; 定義一個(gè)全局的邏輯變;量,變量名為l2l2 SETL FALSE ; 將該變量賦值為假GBLS str3 ; 定義一個(gè)全局的字符串變;量

10、,變量名為str3str3 SETS Hello! ;將該變量賦值為“ Hello!”符號(hào)定義偽指令3-1(3 ) SETA、 SETL 和 SETS格式:變量名SETA/SETL/SETS表達(dá)式說明:SETA:給一個(gè)數(shù)字變量賦值。SETL:給一個(gè)邏輯變量賦值。SETS:給一個(gè)字符串變量賦值。格式中的變量名必須為已經(jīng)定義過的全局或局部變量,表達(dá)式為將要賦給變量的值。符號(hào)定義偽指令3-2例如:LCLA num1 ; 定義一個(gè)局部的數(shù)字;變量,變量名為num1num1 SETA 0x1234 ;將該變量賦值;為 0x1234LCLS str3 ; 定義一個(gè)局部的字符串變;量,變量名為str3str

11、3 SETS“ Hello!將該變”量賦;值為;“Hello! ”符號(hào)定義偽指令44) RLIST格式:名稱RLIST 寄存器列表說明:RLIST可用于對(duì)一個(gè)通用寄存器列表定義名稱,該名稱可在ARM 指令LDM/ STM中使用。在 LDM/STM 指令中,列表中的寄存器為根據(jù)寄存器的編號(hào)由低到高訪問次序,與列表中的寄存器排列次序無關(guān)。例如:pblock RLIST R0-R3,R7,R5 , R9; 將寄存器列表名稱定義為pblock ,可在 ARM 指令;LDM/STM 中通過該名稱訪問寄存器列表數(shù)據(jù)定義偽指令作用:為數(shù)據(jù)分配存儲(chǔ)單元,同時(shí)初始化。有如下幾種:DCB 字節(jié)分配DCW/DCWU

12、半字( 2 字節(jié))分配DCD/DCDU字( 4 字節(jié))分配DCQ/DCQU 8 個(gè)字節(jié)分配DCFS/DCFSU 單精度浮點(diǎn)數(shù)分配DCFD/DCFDU雙精度浮點(diǎn)數(shù)分配SPACE 分配一塊連續(xù)的存儲(chǔ)單元FIELD 定義一個(gè)結(jié)構(gòu)化的內(nèi)存表的數(shù)據(jù)域MAP 定義一個(gè)結(jié)構(gòu)化的內(nèi)存表首地址數(shù)據(jù)定義偽指令1( 1)DCB格式:標(biāo)號(hào)DCB 表達(dá)式說明:分配一塊字節(jié)單元并用偽指令中指定的表達(dá)式進(jìn)行初始化。表達(dá)式可以為使用雙引號(hào)的字符串或0255的數(shù)字。DCB 可用 “ =代”替。例如:Array1 DCB 1,2,3,4,5 ;數(shù)組str1 DCB Your are welcome! ; 構(gòu)造字符串并分配空間數(shù)據(jù)

13、定義偽指令2( 2 ) DCW/DCWU格式:標(biāo)號(hào)DCW/DCWU表達(dá)式說明:DCW 分配一段半字存儲(chǔ)單元并用表達(dá)式值初始化,它定義的存儲(chǔ)空間是半字對(duì)齊的。DCWU 功能與 DCW 類似,只是分配的字存儲(chǔ)單元不嚴(yán)格半字對(duì)齊。例如:Arrayw1 DCW 0xa,-0xb,0xc,-0xd; 構(gòu)造固定數(shù)組并分配半字存儲(chǔ)單元數(shù)據(jù)定義偽指令3( 3 ) DCD/DCDU格式:標(biāo)號(hào)DCD/DCDU表達(dá)式說明: DCD 偽指令用于分配一塊字存儲(chǔ)單元并用偽指令中指定的表達(dá)式初始化,它定義的存儲(chǔ)空間是字對(duì)齊的。DCD 也可用 “ &代”替。DCDU 功能與 DCD 類似,只是分配的存儲(chǔ)單元不嚴(yán)格字對(duì)齊。例如

14、:Arrayd1 DCD 1334, 234 , 345435; 構(gòu)造固定數(shù)組并分配字為單元的存儲(chǔ)單元Label DCD str1; 該字單元存放str1 的地址數(shù)據(jù)定義偽指令4( 4 ) DCQ/DCQU格式:標(biāo)號(hào)DCQ/DCQU表達(dá)式說明:DCQ 用于分配一塊以8 個(gè)字節(jié)為單位的存儲(chǔ)區(qū)域并用偽指令中指定的表達(dá)式初始化,它定義的存儲(chǔ)空間是字對(duì)齊的。DCQU 功能與 DCQ 類似,只是分配的存儲(chǔ)單元不嚴(yán)格字對(duì)齊。例如:Arrayd1 DCQ 234234,98765541; 構(gòu)造固定數(shù)組并分配字為單元的存儲(chǔ)空間。;注意: DCQ 不能給字符串分配空間數(shù)據(jù)定義偽指令5( 5 ) DCFD/DCF

15、DU格式:標(biāo)號(hào)DCFD/DCFDU表達(dá)式說明: DCFD 用于為雙精度的浮點(diǎn)數(shù)分配一片連續(xù)的字存儲(chǔ)單元并用偽指令中指定的表達(dá)式初始化,它定義的存儲(chǔ)空間是字對(duì)齊的。每個(gè)雙精度的浮點(diǎn)數(shù)占據(jù)兩個(gè)字單元。DCFDU 功能與 DCFD 類似,只是分配的存儲(chǔ)單元不嚴(yán)格字對(duì)齊。例如:Arrayf1 DCFD 6E2Arrayf2 DCFD 1.23,1.45數(shù)據(jù)定義偽指令6( 6 ) DCFS/DCFSU格式:標(biāo)號(hào)DCFS/DCFSU 表達(dá)式說明: DCFS 用于為單精度的浮點(diǎn)數(shù)分配一片連續(xù)的字存儲(chǔ)單元并用表達(dá)式初始化,它定義的存儲(chǔ)空間是字對(duì)齊的。每個(gè)單精度浮點(diǎn)數(shù)使用一個(gè)字單元。DCFSU 功能與 DCFS

16、 類似,只是分配的存儲(chǔ)單元不嚴(yán)格字對(duì)齊。例如:Arrayf1 DCFS 6E2, -9E-2 , -.3Arrayf2 DCFSU 1.23,6.8E9數(shù)據(jù)定義偽指令77) SPACE格式:標(biāo)號(hào)SPACE 表達(dá)式說明: SPACE用于分配一片連續(xù)的存儲(chǔ)區(qū)域并初始化為0,表達(dá)式為要分配的字節(jié)數(shù)。SPACE 也可用 “ %”替。代例如:freespace SPACE 1000; 分配 1000 字節(jié)的存儲(chǔ)空間數(shù)據(jù)定義偽指令8(8) MAP格式:MAP表達(dá)式 ,基址寄存器說明: MAP 定義一個(gè)結(jié)構(gòu)化的內(nèi)存表的首地址。此時(shí),內(nèi)存表的位置計(jì)數(shù)器VAR (匯編器的內(nèi)置變量)設(shè)置成該地址值?!?”可以用來

17、代替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 0x130,R2 ; 內(nèi)存表首地址為0x130 R2數(shù)據(jù)定義偽指令9( 9 ) FIELD格式:標(biāo)號(hào)FIELD字節(jié)數(shù)說明: FIELD 用于定義一個(gè)結(jié)構(gòu)化內(nèi)存表中的數(shù)據(jù)域?!?#可”用來代替FIELD 。FIELD 常與 MAP 配合使用來定義結(jié)構(gòu)化的內(nèi)存表: FIELD 偽指令定義內(nèi)存表中的各個(gè)數(shù)據(jù)域, MAP 則定義內(nèi)存表

18、的首地址,并為每個(gè)數(shù)據(jù)域指定一個(gè)標(biāo)號(hào)以供其他的指令引用。需要注意的是MAP 和 FIELD 偽指令僅用于定義數(shù)據(jù)結(jié)構(gòu),并不分配存儲(chǔ)單元。例如:MAP 0xF10000; 定義結(jié)構(gòu)化內(nèi)存表首地址為0xF10000count FIELD 4; 定義 count 的長度為4 字節(jié),位置為0xF1000+0x FIELD 4; 定義 x 的長度為4 字節(jié),位置為0xF1004y FIELD 4; 定義 y 的長度為 4 字節(jié),位置為 0xF1008匯編控制偽指令作用:指引匯編程序的執(zhí)行流程。常用的偽操作包括:( 1 ) MACRO 和 MEND:宏定義的開始與結(jié)束。( 2 )IF 、ELSE 和 EN

19、DIF :根據(jù)邏輯表達(dá)式的成立與否決定是否在編譯時(shí)加入某個(gè)指令序列。( 3 ) WHILE 和 WEND :根據(jù)邏輯表達(dá)式的成立與否決定是否循環(huán)執(zhí)行這個(gè)代碼段。( 4 ) MEXIT :從宏中退出。MACRO 和 MEND格式MACRO$ 標(biāo)號(hào) 宏名$ 參數(shù) 1,$參數(shù) 2, 指令序列MEND其中, $標(biāo)號(hào)在宏指令被展開時(shí),標(biāo)號(hào)可被替換成相應(yīng)的符號(hào)(在一個(gè)符號(hào)前使用 $,表示程序在匯編時(shí)將使用相應(yīng)的值來替代 $后的符號(hào)), $參數(shù) 1 為宏指令的參數(shù),當(dāng)宏指令被展開時(shí)將被替換成相應(yīng)的值,類似于函數(shù)中的形式參數(shù)。宏指令可以重復(fù)使用,與子程序有些類似,子程序可以節(jié)省存儲(chǔ)空間,提供模塊化的程序設(shè)計(jì)。

20、但是使用子程序結(jié)構(gòu)時(shí)需要保存/ 恢復(fù)現(xiàn)場(chǎng),從而增加了系統(tǒng)的開銷。使用說明:在子程序比較短而需要傳遞的參數(shù)比較多的情況下,可使用宏匯編技術(shù)。宏定義偽指令例子MACRO ; 宏定義開始$label jump $a1,$a2 ;宏的名稱為jump ,有 2 個(gè)參數(shù) a1 和 a2$label.loop1 ; $label.loop1為宏體的內(nèi)部標(biāo)號(hào)BGE $label.loop1$label.loop2BL $a1 ; 參數(shù) $a1 為一個(gè)子程序的名稱BGT $label.loop2ADR $a2MEND ; 宏定義結(jié)束宏定義偽指令在程序中調(diào)用該宏exam jump sub,det ;調(diào)用宏 jum

21、p, 宏的標(biāo)號(hào)為exam,參數(shù) 1 為 sub, 參數(shù) 2 為 det程序被匯編后,宏的展開結(jié)果:examloop1BGE examloop1examloop2BL subBGT examloop2ADR detIF 、 ELSE 和ENDIF格式:IF邏輯表達(dá)式代碼段1ELSE代碼段2ENDIF說明:能根據(jù)邏輯表達(dá)式的成立與否決定是否在編譯時(shí)加入某個(gè)指令序列。IF 、ELSE 和ENDIF分別可以用 “ ,”“ ,|”“ 代”替。如果IF后面的邏輯表達(dá)式為真,則編譯代碼段1,否則編譯代碼段 2 。ELSE 及代碼段 2 也可以沒有,這時(shí),當(dāng) IF 后面的邏輯表達(dá)式為真時(shí),則代碼段 1,否則繼

22、續(xù)編譯后面的指令。WHILE和 WEND格式:WHILE邏輯表達(dá)式代碼段WEND說明:WHILE 和 WEND 偽指令能根據(jù)邏輯表達(dá)式的成立與否決定是否循環(huán)執(zhí)行這個(gè)代碼段。當(dāng) WHILE 后面的邏輯表達(dá)式為真時(shí),則執(zhí)行代碼段,該代碼段執(zhí)行完畢后,再判斷邏輯表達(dá)式的值,若為真則繼續(xù)執(zhí)行,一直到邏輯表達(dá)式的值為假。例如:GBLA num ; 聲明全局的數(shù)字變量numnum SETA 9 ; 由 num 控制循環(huán)次數(shù)WHILE num0sub r0,r0,1add r1,r1,1WEND其他偽指令在匯編程序中經(jīng)常會(huì)使用一些其他的偽指令,包括以下18 條:ASSERT AREAALIGN CODE16

23、/CODE32ENTRY ENDEQU IMPORTEXPORT/GLOBAL EXTERNINCBIN GET/INCLUDERN ROUTADR ADRLLDR NOP其他偽指令1( 1 ) ASSERT格式:ASSERT 邏輯表達(dá)式說明: ASSERT 用來表示程序的編譯必須滿足一定的條件,如果邏輯表達(dá)式不滿足,則編譯器會(huì)報(bào)錯(cuò),并終止匯編。例如:ASSERT ver7 ; 保證 ver7其他偽指令22) AREA格式:AREA 段名屬性,說明: AREA 用于定義一個(gè)代碼段、數(shù)據(jù)段或者特定屬性的段。如果段名以數(shù)字開頭,那么該段名需用 “|字”符括起來,如|7wolf| ,用 C 的編譯器

24、產(chǎn)生的代碼一般也用“|括” 起來。屬性部分表示該代碼段/ 數(shù)據(jù)段的相關(guān)屬性,多個(gè)屬性可以用“, ”分隔。常見屬性如下: DATA :定義數(shù)據(jù)段,默認(rèn)屬性是READWRITE 。 CODE:定義代碼段,默認(rèn)屬性是READONLY 。 READONLY:表示本段為只讀。 READWRITE :表示本段可讀寫。 ALIGN= 表達(dá)式,表示段的對(duì)齊方式為2 的表達(dá)式次方,例如:表達(dá)式=3 ,則對(duì)齊方式為 8 字節(jié)對(duì)齊。表達(dá)式的取值范圍為031 。 COMMON 屬性:定義一個(gè)通用段,這個(gè)段不包含用戶代碼和數(shù)據(jù)。其他偽指令(3 ) ALIGN 格式:3ALIGN 表達(dá)式 ,偏移量說明:ALIGN偽操作可

25、以通過填充字節(jié)使當(dāng)前的位置滿足一定的對(duì)齊方式。表達(dá)式的值為2 的冪,如 1 、 2 、4、 8、 16 等,用于指定對(duì)齊方式。如果偽操作中沒有指定表達(dá)式,則編譯器會(huì)將當(dāng)前位置對(duì)齊到下一個(gè)字的位置。偏移量也是個(gè)數(shù)字表達(dá)式,如果存在偏移量,則當(dāng)前位置自動(dòng)對(duì)齊到2 的表達(dá)式值次方偏移量。例如:AREA |.data|,DATA,READWRITE,ALIGN=2其他偽指令4( 4 ) CODE16/CODE32格式:CODE16/CODE32說明: CODE16 偽操作指示編譯器后面的代碼為16 位的Thumb指令。 CODE32偽操作指示編譯器后面的代碼為32 位的ARM 指令。如果在匯編源代碼中

26、同時(shí)包含Thumb和 ARM 指令時(shí),可以用“CODE32”通知編譯器后的指令序列為32 位的ARM 指令,用 “CODE16”偽指令通知編譯器后的指令序列為16 位的Thumb指令。CODE16/CODE32 不能對(duì)處理器進(jìn)行狀態(tài)的切換。例如:CODE32 ; 32 位的 ARM 指令A(yù)REA |.text|,CODE, READONLYLDR R0, 0x8500;BX R0 ; 程序跳轉(zhuǎn),并將處理器切換到Thumb 狀態(tài)CODE16 ;16 位的 Thumb 指令A(yù)DD R3,R3,1END ; 源文件結(jié)束其他偽指令5-1( 5 ) ENTRY格式:ENTRY說明: ENTRY 用于指定

27、匯編程序的入口。在一個(gè)完整的匯編程序中至少要有一個(gè) ENTRY,程序中也可以有多個(gè),此時(shí),程序的真正入口點(diǎn)可在鏈接時(shí)指定,但在一個(gè)源文件里最多只能有一個(gè) ENTRY 或者沒有 ENTRY。其他偽指令5-2其他偽指令6( 6)END格式:END說明: END 告訴編譯器已經(jīng)到了源程序的結(jié)尾。例如:AREA constdata ,DATA , READONLYEND ; 結(jié)尾其他偽指令7( 7)EQU格式:名稱EQU 表達(dá)式 ,類型 說明: EQU 用于將程序中的數(shù)字常量、標(biāo)號(hào)、基于寄存器的值賦予一個(gè)等效的名稱,這一點(diǎn)類似于 C 語言中的 define.可用 “*代”替 EQU。如果表達(dá)式為32

28、位的常量,我們可以指定表達(dá)式的數(shù)據(jù)類型,類型域可以有以下3 種:CODE16/CODE32/DATA例如:num1 EQU 1234 ;定義 num1 為 1234addr5 EQU str1+0x50d1 EQU 0x2400 , CODE32 ; 定義 d1 的為 0x2400 ,且該處為32 位的 ARM 指令其他偽指令8( 8 ) EXPORT/GLOBAL格式:EXPORT/GLOBAL 標(biāo)號(hào),WEAK說明: EXPORT 在程序中聲明一個(gè)全局標(biāo)號(hào),其他文件中的代碼可以被該標(biāo)號(hào)引用。用戶也可以用 GLOBAL 代替 EXPORT。,WEAK 可選項(xiàng)聲明其他文件有同名的標(biāo)號(hào),則該同名標(biāo)

29、號(hào)優(yōu)先于該標(biāo)號(hào)被引用。例如:AREA |.text|,CODE,READONLYmain PROCENDPEXPORT main ; 聲明一個(gè)可全局引用的函數(shù)mainEND其他偽指令9( 9 ) IMPORT格式:IMPORT 標(biāo)號(hào),WEAK說明:告訴編譯器, 這個(gè)標(biāo)號(hào)要在當(dāng)前源文件中使用,但標(biāo)號(hào)是在其他的源文件中定義的。,WEAK :如果所有的源文件都沒有找到這個(gè)標(biāo)號(hào)的定義,編譯器也不會(huì)提示錯(cuò)誤信息,同時(shí)編譯器也不會(huì)到當(dāng)前沒有被INCLUDE 進(jìn)來的庫中去查找該符號(hào)。例如:AREA mycode,CODE,READONLYIMPORT _ printf; 通知編譯器當(dāng)前文件要引用函數(shù)_ pr

30、intfENDIMPORT使用說明使用 IMPORT 為操作聲明一個(gè)符號(hào)是在其他源文件中定義的。如果鏈接器在鏈接處理時(shí)不能解析該符號(hào),而且IMPORT 為操作中沒有指定WEAK 選項(xiàng),則鏈接器將會(huì)報(bào)告錯(cuò)誤。如果鏈接器在鏈接處理時(shí)不能解析該符號(hào),而IMPORT 偽操作中指定了WEAK 選項(xiàng),則鏈接器不會(huì)報(bào)告錯(cuò)誤,而是進(jìn)行下面的操作:如果該符號(hào)被B 或 BL 指令引用,則該符號(hào)被設(shè)置成下一條指令的地址,該B 或者 BL 指令相當(dāng)于一條NOP 指令。例如 “B sign ,”“sign不”能被解析,則該指令被忽略為NOP 指令,繼續(xù)執(zhí)行下面的指令,也就是將sign 理解為下一條指令的地址。其他情況下

31、該符號(hào)被設(shè)置為0。其他偽指令1010 ) EXTERN格式:EXTERN 標(biāo)號(hào),WEAK說明:告訴編譯器, 標(biāo)號(hào)要在當(dāng)前源文件中引用,但是該標(biāo)號(hào)是在其他的源文件中定義的。與 IMPORT 不同的是,如果當(dāng)前源文件實(shí)際上沒有引用該標(biāo)號(hào),該標(biāo)號(hào)就不會(huì)被加入到當(dāng)前文件的符號(hào)表中。,WEAK :即使所有的源文件都沒有找到這個(gè)標(biāo)號(hào)的定義,編譯器也不給出錯(cuò)誤信息。例如:AREA |.text|,CODE,READONLYEXTERN _ printf,WEAK ;告訴編譯器當(dāng)前文件要引用標(biāo)號(hào),如果找不到,則不提示錯(cuò)誤END其他偽指令11( 11 )GET/INCLUDE格式:GET 文件名說明: GET

32、將一個(gè)源文件包含到當(dāng)前的源文件中,并將被包含的源文件在當(dāng)前位置展開進(jìn)行匯編處理。INCLUDE 和 GET 的作用是等效的。使用方法:在某源文件中定義一些宏指令,用 MAP 和 FIELD 定義結(jié)構(gòu)化的數(shù)據(jù)類型,用 EQU定義常量的符號(hào)名稱,然后用GET/INCLUDE 將這個(gè)源文件包含到其他的源文件中。使用方法與C 語言中的 “#include相”似。GET/INCLUDE只能用于包含源文件,包含其他文件則需要使用INCBIN偽指令。例如:AREA mycode,DATA,READONLYGET E: codeprog1.s ;通知編譯器在當(dāng)前源文件包含源文件GET prog2.s ; 通知

33、編譯器當(dāng)前源文件包含可搜索目錄下的E: code prog1.sprog2.sEND其他偽指令12( 12 )INCBIN格式:INCBIN文件名說明: INCBIN 將一個(gè)數(shù)據(jù)文件或者目標(biāo)文件包含到當(dāng)前的源文件中,編譯時(shí)被包含的文件不作任何變動(dòng)地存放在當(dāng)前文件中,編譯器從后面開始繼續(xù)處理。例如:AREA constdata,DATA,READONLYINCBIN data1.dat ;源文件包含文件data1.datINCBIN E : DATAdata2.bin; 源文件包含文件E: DATAdata2.binEND其他偽指令13( 13 )RN格式:名稱RN 表達(dá)式說明: RN 用于給一

34、個(gè)寄存器定義一個(gè)別名,以便程序員記憶該寄存器的功能。名稱為給寄存器定義的別名,表達(dá)式為寄存器的編碼。例如:count RN R1 ; 給 R1 定義一個(gè)別名count其他偽指令14( 14 )ROUT格式: 名稱 ROUT說明: ROUT 可以給一個(gè)局部變量定義作用范圍。在程序中未使用該偽指令時(shí),局部變量的作用范圍為所在的AREA,而使用 ROUT 后,局部變量的作用范圍為當(dāng)前ROUT 和下一個(gè)ROUT之間。例如:routine ROUT ;定義局部標(biāo)號(hào)的有效范圍1 routine; routine內(nèi)的局部標(biāo)號(hào)1BEQ %1 routine ;若條件成立,則跳轉(zhuǎn)到routine范圍內(nèi)的局部標(biāo)號(hào)

35、1Otherroutine ROUT;定義新的局部標(biāo)號(hào)的有效范圍其他偽指令14( 15 )LTORG說明: LTORG 用于聲明一個(gè)數(shù)據(jù)緩沖池(literal pool )的開始。通常放在無條件跳轉(zhuǎn)指令之后,或者子程序返回指令之后,以免處理器錯(cuò)誤地將數(shù)據(jù)緩沖池中地?cái)?shù)據(jù)作為指令來執(zhí)行。例如:Func1MOV PC, LRLTORGDATA SPACE 26; 從 data 標(biāo)號(hào)開始預(yù)留256 字節(jié)地內(nèi)存單元END其他偽指令15( 16 )ADR 小范圍地址讀取格式:ADR ,;說明:將基于PC 相對(duì)偏移的地址值或基于寄存器相對(duì)偏移的地址值(expr地址表達(dá)式)讀取到目標(biāo)寄存器Rd 中。當(dāng)?shù)刂分凳?/p>

36、非字對(duì)齊時(shí),取值范圍在-255255字節(jié)之間;當(dāng)?shù)刂分凳亲謱?duì)齊時(shí),取值范圍在-1 020 1 020 字節(jié)之間。在匯編編譯源程序時(shí),ADR 偽指令被編譯器替換成一條合適的指令。通常 ,編譯器用一條ADD 指令或 SUB 指令來實(shí)現(xiàn)該ADR 偽指令的功能。若不能用一條指令實(shí)現(xiàn) ,則產(chǎn)生錯(cuò)誤 ,編譯失敗。對(duì)于基于 PC 相對(duì)偏移的地址值時(shí),給定范圍是相對(duì)當(dāng)前指令地址后兩個(gè)字處(因?yàn)锳RM7TDMI 為三級(jí)流水線) ??梢杂?ADR 加載地址實(shí)現(xiàn)查表。例如:LOOP MOV R1 , #0xF0ADR R2 , LOOP ;將 LOOP 的地址放入R2 ,因?yàn)?PC 值為當(dāng)前指令地址值加本 ADR

37、偽指令將被編譯器換成“SUB R2,PC, 0XC”8 字節(jié),所以其他偽指令16( 17 )ADRL 中等范圍地址讀取格式:ADRL ,;說明:類似于ADR, 但比 ADR 讀取更大范圍的地址。當(dāng)?shù)刂分凳欠亲謱?duì)齊時(shí),取值范圍在-64KB 64 KB之間;地址值是字對(duì)齊時(shí),取值范圍在-256KB256 KB之間。在匯編編譯源程序時(shí),ADRL 偽指令被編譯器替換成兩條合適的指令。若不能用兩條指令實(shí)現(xiàn)ADRL 偽指令功能,則產(chǎn)生錯(cuò)誤,編譯失敗??梢杂?ADRL 加載地址,實(shí)現(xiàn)程序跳轉(zhuǎn)。例如:ADRL R0 ,DATA_BUFADRL R1 ,DATA_BUF+80DATA_BUFSPACE 100

38、;定義 100 字節(jié)緩沖區(qū)其他偽指令17( 18 )LDR 大范圍地址讀取格式:LDR ,;說明:加載32 位的立即數(shù)或一個(gè)地址值到目標(biāo)寄存器Rd。在匯編編譯源程序時(shí),LDR 偽指令被編譯器替換成一條合適的指令。若加載的常數(shù)未超出MOV或MVN的范圍,則使用MOV 或MVN指令代替該LDR 偽指令;否則匯編器將常量放入文字池,并使用一條程序相對(duì)偏移的LDR 指令從文字池讀出常量。LDR 用于加載芯片外圍功能部件的寄存器地址(32位立即數(shù)),以實(shí)現(xiàn)各種控制操作。從PC到文字池的偏移量必須小于4 KB。與 ARM 指令的 LDR 相比,偽指令的LDR 的參數(shù)有 “ ”符號(hào)。例如:LDR R0 ,

39、=0x12345678;加載 32 位立即數(shù)0x12345678LDR R0 , =DATA_BUF+60;加載DATA_BUF地址 +60LTORG;聲明文字池其他偽指令18( 19 )NOP 空操作格式:NOP ;說明:不產(chǎn)生任何有意義的操作,只是占用一個(gè)機(jī)器時(shí)間。NOP 偽指令在匯編時(shí)將會(huì)被替代成ARM 中的空操作,比如可能為“ MOV R0,R0指”令等。簡單的 ARM 匯編程序設(shè)計(jì)(一)查表和散轉(zhuǎn)程序設(shè)計(jì)當(dāng)涉及到數(shù)據(jù)串或者跳轉(zhuǎn)表格時(shí), 常常需要通過地址對(duì)他們進(jìn)行訪問, 通常有兩種方法裝載地址:通過 ADR 和 ADRL 偽指令直接裝載地址;通過偽指令LDR Rd , label 從數(shù)

40、據(jù)池中裝載地址。下面以程序jump.s 為例,介紹通過ADR 偽指令裝載地址地散轉(zhuǎn)程序地設(shè)計(jì)。查表和散轉(zhuǎn)程序設(shè)計(jì)主程序中設(shè)置了3 個(gè)參數(shù), arithfunc當(dāng) R0 0 時(shí), R0:=R1+R2;當(dāng) R0 1 時(shí), R0:=R1-R2;根據(jù)3 個(gè)參數(shù)返回一個(gè)R0 值。簡單的 ARM 匯編程序設(shè)計(jì)(一)查表和散轉(zhuǎn)程序設(shè)計(jì)num EQU 2 ;跳轉(zhuǎn)表的入口數(shù)目ENTRY ; 程序入口startMOV r0, #0 ;設(shè)置 3 個(gè)參數(shù)MOV r1, #3MOV r2, #2BL arithfunc ;調(diào)用子程序Stop ;執(zhí)行中止MOV r0, #0x18 ;軟中斷參數(shù)設(shè)置LDR r1, =0x2

41、0026 ;軟中斷參數(shù)設(shè)置SWI 0x123456 ;將 CPU 的控制權(quán)交給調(diào)試器ARM; semihosting SWI查表和散轉(zhuǎn)程序設(shè)計(jì)續(xù)arithfunc ;CMP r0, #num ;比較參數(shù)MOVHS pc, lr ;若超出范圍則程序返回ADR r3, JumpTable ;裝載跳轉(zhuǎn)表格標(biāo)號(hào)地址LDR pc, r3,r0,LSL#2 ;跳轉(zhuǎn)到相應(yīng)子程序入口地址處JumpTableDCD DoAddDCD DoSubDoAddADD r0, r1, r2 ; 0MOV pc, lr ;返回DoSubSUB r0, r1, r2 ; 1MOV pc,lr ;返回END ;程序結(jié)尾時(shí)的操

42、作時(shí)的操作軟中斷指令SWISemihosting在 ADS 的 C 語言函數(shù)庫中, 某些 ANSIC 的功能是由主機(jī)的調(diào)試環(huán)境來提供的,這套機(jī)制有一個(gè)專門術(shù)語叫Semihosting 。Semihosting通過一組軟件中斷(SWI)指令來實(shí)現(xiàn)。當(dāng)一個(gè)Semihosting軟中斷被執(zhí)行時(shí),調(diào)試系統(tǒng)先識(shí)別這個(gè)SWI請(qǐng)求,然后掛起正在運(yùn)行的程序,調(diào)用Semihosting的服務(wù),完成后再恢復(fù)原來的程序執(zhí)行。因此,主機(jī)執(zhí)行的任務(wù)對(duì)于程序來說是透明的。SWI 傳遞的功能號(hào)( 例如:semi-hosting,使用 0x123456 (ARM) or 0xAB (Thumb)續(xù)在此例中, 表格 jumptable 中存放地是子程序地入口地址, 我們把這種表格稱為跳轉(zhuǎn)表格。注意指令 LDR PC, R3,R0,LSL #2, 執(zhí)行地操作為 PC R3 R04,因?yàn)楸砀裰写娣?/p>

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論