版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、第5章 ARM匯編程序設計ARM編譯器,如ADS集成開發(fā)環(huán)境,一般都支持匯編語言的程序設計。本章介紹ARM程序設計的一些基本概念,如ARM匯編語言的偽指令、匯編語言的語句格式和匯編語言的程序結(jié)構(gòu)等到,并在些基礎上介紹一些常用的ARM匯編子程序的設計。4.1 ARM偽指令ARM匯編程序由匯編指令、偽指令和宏指令組成,偽指令不介匯編指令那樣在處理器的運行期間執(zhí)行,而是在匯編器對匯編程序進行匯編時處理。宏是一段獨立的匯編程序代碼,它是通過偽指令定義的,在程序中宏指令即調(diào)用宏指令。當程序被匯編時,匯編程序?qū)γ總€宏調(diào)用進行展開,用宏定義代匯編程序中的宏指令。由于指令也發(fā)球匯編偽指令的一部分,因此本書將宏
2、指令放在匯編偽一起介紹。與單片機匯編程序設計一樣,在ARM匯編語言程序里,有一些特殊指令助記符,這些助記符與指令系統(tǒng)的助記符不同,它們沒有相對應的操作友碼,通常稱這些特殊指令助記符為偽指令,它們所完成的操作稱為偽操作。偽指令在源程序中的作用是為完成匯編程序做各種準備工作,這些偽指令僅在匯編過程中起作用,一旦匯編結(jié)束,偽指令的使命就完成了。在ARM的光榮稱號程序中,有如下幾種偽指令:符號定義偽指令、數(shù)據(jù)定義偽指令、匯編控制偽指令以及其他偽指令。4.1.1 符號定義(Symbol Definition)偽指令符號定義偽指令用于定義ARM匯編程序中的變量、對變量賦值以及定義寄存器的別名等。常見的符號
3、定義偽指令有以下幾種:l 用于寶玉局變量的GBLA、GBLL和GBLS;l 用于定義局部變量的LCLA、SETL、LCLS;l 用于對變量賦值的SETA、SETL、SETS;l 為通用寄存器列表定義名稱的RLIST;l 為一個協(xié)處理器的寄存器定義名稱的偽指令CN;l 為一個協(xié)處理器定義名稱的偽指令CP;l 為一個CFP寄存器定義名稱的偽指令DN和SN;l 為一個FPA浮點寄存器定義名稱的偽指令FN。1. GBLA、GBLL和GBLS語法格式:GBLA(GBLL或GBLS) 全局變量名GBLA、GBLL和GBLS偽指令用于定義一個ARM程序中的全局變量,并半其初始化。其中:GBLA偽指令用于定義
4、一個全局的數(shù)字變量,并初始化為0;GBLL偽指令用于定義一個全局的邏輯變量,并初始化為F(假);GBLS偽指令用于定義一個全局的字符串變量,并初始化為空。由于以上三條偽指令用于定義全局變量,因此在整個程序范圍內(nèi)變量名必須唯一。使用示例:GBLA Number1 ;定義一個全局的數(shù)字變量,變量名為Number1Number1 SETA 0xaa ;將Number1變量賦值為0xaaGBLL True1 ;定義一個全局的邏輯變量,變量名為True1True1 SETLTRUE;將True1變量賦值為真GBLS String1 ;定義一個全局的字符串變量,變量名為String1 String1 SE
5、TS“Testing” ;將String1變量賦值為“Testing”2. LCLA、LCLL和 LCLS語法格式:LCLA(LCLL或LCLS) 局部變量名LCLA、LCLL和LCLS偽指令用于定義一個ARM程序中的局部變量,并將其初始化,其中:l LCLA偽指令用于定義一個局部的數(shù)字變量,并初始化為0;l LCLL偽指令用于定義一個局部的邏輯變量,并初始化為F(假);l LCLS偽指令用于定義一個局部的字符串變量,并初始化為空。以上三條偽指令用于聲明局部變量,在其作用范圍內(nèi)變量名必須唯一。使用示例:LCLA Number2 ;聲明一個局部的數(shù)字變量,變量名為Number2 Number2
6、SETA 0xaa ;將Number2 變量賦值為0xaaLCLL Logic2 ;聲明一個局部的邏輯變量,變量名為Logic2Logic2 SETLTRUE ;將Logic2變量賦值為真LCLS String2 ;定義一個局部的字符串變量,變量名為String2String2 SETS“Testing” ;將String2變量賦值為“Testing”3. SETA、SETL和SETS語法格式:變量名 SETA(SETL或SETS) 表達式偽指令SETA、SETL、SETS用于給一個已經(jīng)定義的全局變量或局部變量賦值。l SETA偽指令用于給一個數(shù)學變量賦值;l SETL偽指令用于給一個邏輯變量
7、賦值;l SETS偽指令用于給一個字符串變量賦值。其中,變量名是已經(jīng)定義地的全局變量或局部變量,表達式是將要賦給變量的值。使用示例:LCLA Number3 ;聲明一個局部的數(shù)字變量,變量名為Number3Number3 SETA 0xaa ;將Number3變量賦值為0xaaLCLL Logic3 ;聲明一個局部的邏輯變量,變量名為Logic3Logic3 SETLTRUE了 ;將Logic3變量賦值為真4. RLIST語法格式:名稱 RLIST 寄存器列表RLIST偽指令可用于對一個通用寄存器列表定義名稱,使用該偽指令定義的名稱可在ARM指令LDM/STM中使用。在LDM/STM指令中,列
8、表中的寄存器訪問次序為根據(jù)寄存器的編號由低到高,而與列表中的寄存器排列次序無關(guān)。使用示例:RegList RLIST R0-R5,R8,R10 ;將寄存器列表名稱定義為RegList,可在ARM ;指令LDM/STM中通過該名稱訪問寄存器列表STMD SP!,RegList ;保存寄存器列表RegList 到堆棧由于在編程過程中,協(xié)處理器匯編偽指令使用的情況比較少,因此本書不對CP、DN和SN以及FN等協(xié)處理器偽指令進行介紹。4.1.2 數(shù)據(jù)定義(DATA Definition)偽指令數(shù)據(jù)定義偽指令一般用于為特定的數(shù)據(jù)分配存儲單元,同時可完成對已分配存儲單元的初始化。常見的數(shù)據(jù)定義偽指令有如下
9、幾種:l DCB用于分配一片連續(xù)的字節(jié)存儲單元并用指定的數(shù)據(jù)初始化;l DCW(DCWU)用于分配一片連續(xù)的半字節(jié)存儲單元并用指定的數(shù)據(jù)初始 化;l DCD(DCDU)用于分配一片連續(xù)的字存儲單元并用指定的數(shù)據(jù)初始 化;l DCFS(DCFSU)用于為雙精度的浮點數(shù)分配一片連續(xù)的字存儲單元并用指定的數(shù)據(jù)初始化;l DCQ(DCQU)用于分配一片以8字節(jié)個為單位的連續(xù)的存儲單元并用指定的數(shù)據(jù)初始化;l DCDO用于分配一段字的內(nèi)存單元,將每個單元的內(nèi)容初始化為該單元相對于基址寄存器的偏移量;l DCI用于分配一段字的內(nèi)豐單元,并用單精度的浮點數(shù)據(jù)初始化,指定內(nèi)存單元存放的是代碼,而不是數(shù)據(jù);l
10、SPACE用于分配一片連續(xù)的存儲單元;l MAP用于定義一個結(jié)構(gòu)化的內(nèi)存表首地址;l FIELD用于定義一個結(jié)構(gòu)化的內(nèi)在表的數(shù)據(jù)域;l LTORG用于聲明一個文字池。1.語法格式:標號 DCB 表達式DCB偽指令用于分配一片連續(xù)的字節(jié)存儲單元并用偽指令中的表達式初始化。其中,表達式可以為0255的數(shù)字或字符呂,DC也可用“=”代替。使用示例:標號 DCB 表達式DCB偽指令用于分配一片連續(xù)的字節(jié)存儲單元并用偽指令中指定的表達式初始化。其中,表達式可以為0255的數(shù)字或字符串,DCB也可用“=”代替。使用示例:String DCB “This is a test!” ;分配一片連續(xù)的字節(jié)存儲單元
11、并初始化Parameter DCB 0x33,0x44,0x55DCB -1,-2,0,1,2, ;分配一片連續(xù)的字節(jié)存儲單元并初始化2. DCW(或DCWU)語法格式:標號 DCW(或DCWU) 表達式DCW(或DCWU)偽指令用于為雙精度的浮點數(shù)分配一片連續(xù)的字節(jié)存儲單元,并用偽指令中指定的表達式初始化。每個雙精度的浮點數(shù)占據(jù)兩個字單元,用DCFD分配的字存儲單元是字對齊的,而用DCFDU分配的字存儲單元并不嚴格字對齊。使用示例:Fdata DCFD 0,2E115。-5E7 ;分配一片連續(xù)的字存儲單元并初始化為指定的雙精度數(shù)5. DCFS(或DCFSU) 語法格式:標號 DCFS(或DC
12、FSU) 表達式DCFS(或DCFSU)偽指令用于為單精度的浮點數(shù)分配一片連續(xù)的字存儲單元,并用偽指令中指定的表達式初始化。每個單精度的浮點數(shù)占據(jù)一個字單元,用DCFS分配的字存儲單元是字對齊的,而用DCFSU分配的字存儲單元并不嚴格對齊。使用示例:Sdata DCFS 1,2E5,-5E7 ;分配一片連續(xù)的字存儲單元并初始化為指定的單精度數(shù)6. DCQ(或DCQU)語法格式:標號 DCQ(或DCQU) 表達式DCQ(或DCQU)偽指令用于分配一片以8個字節(jié)為單位的連續(xù)存儲區(qū)域,并用偽指令中指定的表達式初始化。用DCQ分配的存儲單元是字對齊的,而用DCQU分配的存儲單元并不嚴格對齊。使用示例:
13、Data DCQ 100,1000 ;分配一片連續(xù)的存儲單元并初始化為指定的值7. DCDO語法格式:標號 DCDO 表達式DCDO用于分配一段字內(nèi)存單元,并將每個單元的內(nèi)容初始化為該單元相對于表態(tài)基址寄存器的偏移量。DCDO偽指令作為表態(tài)基址寄存器R9的偏移量分配內(nèi)在單元,該指令需要內(nèi)在字對齊。使用示例:IMPORT externsysData DCDO externnsys ;分配32位的字單元,其值勤為標號externnsys 基于R9的偏移量8. DCI語法格式:標號 DCI 表達式DCI用于分配一段字節(jié)的內(nèi)在單元,并用偽指令中指定的表達式初始化。指定內(nèi)在單元存放的是代碼而不是數(shù)據(jù),在
14、Thumb代碼中,DCI分配的是半字節(jié)的內(nèi)存代碼單元。使用示例:MACRO ;這個宏指令將指令 newinstr Rd,Rm定義為相應的機器指令Newinstr $Rd,$RmDCI 0Xe15f0f10:CR:(8$Rd:SHL:12):OR;$Rm ;這是存放的是指令MEND9. SPACE語法格式:標號 SPACE 表達式SPACE偽指令用于分配一片連續(xù)的存儲區(qū)域并初始化為0。其中,表達式是要分配的字節(jié)數(shù),SPACE也可用“%”代替。使用示例:DataSpace SPACE 1000 ;分配連續(xù)1000B的存儲單元并初始化為010. MAP語法格式:MAP 表達式,基址寄存器MAP偽指令
15、用于定義一個結(jié)構(gòu)化的內(nèi)存表的首地址,MAP也可用“”代替。表達式可以是程序中的標號或數(shù)學表達式,基址寄存器為可選項,當基址寄存器選項不存在時,表達式的值即為內(nèi)存表的首地址,當該選項存在時,內(nèi)存表的首地址為表達式的值與基址寄存器的和。MAP偽指令通常與FIELD偽指令配合使用來定義結(jié)構(gòu)化的內(nèi)存表。使用示例:MAP 0x10,R0 ;定義結(jié)構(gòu)化內(nèi)存表首地址的值為0x10+R011. FIELD語法格式:標號 FIELD 表達式FIELD偽指令用于定義一個結(jié)構(gòu)化內(nèi)存表中的數(shù)據(jù)域。FIELD也可用“#”代替,表達式的值是當前數(shù)據(jù)域在內(nèi)存表中所占的字節(jié)數(shù)。FIELD偽指令常與MAP偽指令配合使用來定義結(jié)
16、構(gòu)化的內(nèi)存表,MAP偽指令定義內(nèi)存表的首地址,F(xiàn)IELD偽指令定義內(nèi)存表中的各個數(shù)據(jù)域,并可以為每個數(shù)據(jù)域指定一個標號供其他的指令引用。注意MAP和FIELD偽指令僅用于定義數(shù)據(jù)結(jié)構(gòu),并不實際分配存儲單元。使用示例:MAP 0x100 ;定義結(jié)構(gòu)化內(nèi)存表首地址的值為為0x100A FIELD 16 ;定義A的長度為16B,位置為0x100B FIELD 32 ;定義B的長度為32B,位置為0x110(0x100的存放了 ;16個字節(jié)) S FIELD 256 ;定義S的長度為256B,位置為0x130(0x100后存放了 ;32個字節(jié))12. LTORG語法格式:LTORGLTORG用于聲明一
17、個文字池。在使用LDR偽指令時,要在適當?shù)牡刂芳尤隠TORG聲明文字池,這樣就會把要加載的數(shù)據(jù)保存在文字池中,再用ARM的加載指令讀出數(shù)據(jù)。如果沒有使用LTORG聲明文字池,則匯編器會在程序末尾自動聲明,使用LTORG聲明文字池的目的可以在程序代碼的任何位置存儲加載的數(shù)據(jù)。使用示例:LDR R0,=0x12345ADD R1,R1,R0MOV PC,LRLTORG ;聲明文字池,此處存放0x12345 ;其他代碼4.1.3 匯編控制(Assembly Control)偽指令匯編控制偽指令用于控制匯編程序的執(zhí)行流程,包括以下常用的匯編控制偽指令:l IF、ELSE、ENDIFl WHILE、WE
18、NDl MACRO、MENDl MEXIT1.IF、ELSE、ENDIF語法格式:IF 邏輯表達式 指令序列1ELSE 指令序列2ENDIFIF、ELSE、ENDIF偽指令能夠根據(jù)條件的成立與否決定是否執(zhí)行某個指令序列。若IF后面的邏輯表達式為真,則執(zhí)行指令序列1,否則執(zhí)行指令序列2。其中,ELSE及指令序列2可以沒有,此時,若IF后面的邏輯表達式為真,則執(zhí)行指令序列1,否則繼續(xù)執(zhí)行后面的指令。IF、ELSE、ENDIF偽指令可以嵌套使用。使用示例:GBLS Version ;定義一個全局的字符串變量,變量名為VersionIF Version=“V1” 指令序列1ELSE 指令序列2ENDI
19、F2. WHILE、WEND語法格式:WHILE 邏輯表達式 指令序列WENDWHILE、WEND偽指令能夠根據(jù)條件的成立與否決定是否循環(huán)執(zhí)行某個指令序列。若WHILE后面的邏輯表達式為真,則執(zhí)行指令序列,該指令序列執(zhí)行完畢后,再判斷邏輯表達式的值,若為真則繼續(xù)執(zhí)行,一直到邏輯表達式的值為假。WHILE、WEND偽指令可以嵌套使用。使用示例如下:GBLA Counter ;聲明一個全局的的數(shù)字變量,變量名為Counter,作為循環(huán)計數(shù)器WHILE Counter<10 指令序列WEND3. MACRO、MEND語法格式:$標號 宏名$參數(shù)1,$參數(shù)2,指令序列MENDMACRO、MEND
20、偽指令可以將一段代碼定義為一個整體,稱為宏指令,然后就可以在程序中通過宏指令多次調(diào)用該段代碼。其中,$標號在宏指令被展開時,標號會被替換為用戶定義的符號,宏指令可以使用一個或多個參數(shù),當宏指令被展開時,這些參數(shù)被相應的值替換。宏指令的使用方式和功能與子程序相似,子程序可以提供模塊化的程序設計,節(jié)省存儲空間并提高運行速度。包含在MAMEND之間的指令序列稱為宏定義體,在宏定義的第一行應聲明宏的原型(包含宏名、所需的參數(shù)),然后就可以在匯編程序中通過宏名來調(diào)用該指令序列。MACRO、MEND可以嵌套使用。使用示例如下:MACRO CODE_1 ;宏名為CODE_1,無參數(shù) LDR R0,=rPDA
21、TG ;讀取PG0口的值 LDR R1,R0 ORR R1,R1,#0X01 ;CSI置位 SRT R1,R0MEND4. MEXIT語法格式:MEXITMEXIT用于從宏定義中跳轉(zhuǎn)出去4.1.4 其他常用的偽指令還有一些其他的偽指令,在匯編程序中經(jīng)常會被使用,下面是一些使用比較頻繁的偽指令:l AREAl ALIGNl CODE16、CODE32l ENTRYl ENDl EQUl EXPORT(GLOBAL)l IMPORTl EXTERNl GET(INCLUDE)l INCBINl RNl ROUT4.2 匯編語法4.2.1 匯編程序源文件ARM匯編源程序文件是文本文件格式,可以使用任
22、意一種文本編輯器編寫程序代碼。通常情況下,ARM項目中的源程序文件具有如表4.1所示的擴展名。表4.1 ARM項目中的源程序文件及擴展名源程序文件擴展名匯編源程序.s包含文件.incC文件.c頭文件.h在一個項目設計中,至少需要有一個匯編源文件或C程序文件,可以有多個匯編文件、多個C程序文件或者C語言和匯編語言混合編程的文件。4.2.2 匯編語句語法1. 匯編語句格式ARM(Thumb)匯編語言的語句格式為:標號 指令或偽指令 ;注釋在匯編語言程序設計中,每一條指令的助記符可以全部用大寫或全部用小寫,但不允許一條指令中大、小寫混用。同時,如果一條語句太長,可半該長語句分為若干行來書寫,在行的末
23、尾用“”表示下一行與本行為同一條語句。匯編語句的注釋用“;”,注釋內(nèi)容由“;”開始到此行結(jié)束,注釋可以在一行的頂頭書寫。對于變量的設置、常量的定義,其標識符必須在一行的頂頭書寫。源程序中允許有空行,適當?shù)牟迦肟招锌梢蕴岣叱绦虻目勺x性。匯編語句正確的例子和錯誤的例子如下:String1 SETS"My string1"Count RN R0USR_STRACK EQU 64START LDR R0,=0x12345 MOV R1,#0LOOP MOV R2,#3錯誤的例子:START MOV R0,#1 ;標號START沒有頂頭寫(START前有空格)ABC: MOV R1,
24、#2 ;標號ABC后不能帶“:”MOV R2,#3 ;MOV指令不允許頂頭寫(MOV前要有空格)Loop MOV R2,#3 ;指令中有大、小寫混合B loop ;無法跳轉(zhuǎn)到loop去(loop與Loop有區(qū)別)2. 標號在ARM匯編中,標號代表一個地址,段內(nèi)標號的地址在匯編時確定,而段外標號的地址在連接時確定,根據(jù)標號的生成方式,可以有以下3種方式:1) 基于PC的標號基于PC的標號是位于目標指令前的標號或程序中的數(shù)據(jù)定義偽指令前的標號,這種標號在匯編時被處理成PC值加上或減去一個數(shù)字常量,它常用于跳轉(zhuǎn)指令的目標地址,或代碼段中所嵌入的少量數(shù)據(jù)。2) 基于寄存器的標號基于寄存器的標號通常由M
25、AP和FIELD偽指令定義,也可以用EQU偽指令定義。這種標號在匯編時被處理成寄存器的值加上或減去一個數(shù)字常量。它通常用于訪問位于數(shù)據(jù)段中的數(shù)據(jù)。3) 絕對地址絕對地址是一個32位的數(shù)字,它可以尋址的范圍是02321,可以直接尋址整個內(nèi)存空間。3. 常用符號在匯編語言程序設計中,經(jīng)常使用各種符號代替地址、變量和常量等,以增加程序的可讀性。盡管符號的命名由編程者決定,但并不是任意的,必須遵循以下的決定:l 符號由大、小寫字母、數(shù)字以及下劃線組成;l 除局部標號以數(shù)字開頭外,其他的符號不能以數(shù)字開頭;l 符號區(qū)分大、小寫,同名的大、小寫符號會被編譯器認為是兩個不同的符號;l 符號在其作用范圍內(nèi)必須
26、唯一;l 自定義的符號不能與系統(tǒng)的保留子相同;l 符號名不應與指令或偽指令同名。1)程序中的變量程序中的變量是指其值在程序的運行過程中可以改變的量。ARM匯編程序所支持的變量有數(shù)字變量、邏輯變量和字符串變量。2) 程序中的常量程序中的常量是指其值在程序的運行過程中不能被改變的量。ARM匯編程序所支持的常量有數(shù)字常量、邏輯常量和字符串常量。數(shù)字常量一般為32位的整數(shù),其取值范圍為2312311。數(shù)字常量有3種表示方式:l 十進制數(shù),如12,4,2,4等;l 十六進制數(shù),如0x32,0xFF,0x0等;l n進制數(shù),用n-XXX表示,其中n為為9,XXX為具體的數(shù),如2-0100101,8-432
27、13等。邏輯常量(又叫布爾常量)只有兩種取值情況:真TRUE或假FALSE。比如:Isright SETSFALSE字符串常量為一個固定的字符串,一般用于程序運行時的信息提示,比如:Hello SETS"Hello World!"Error SETS"The parameter is error"4. 程序中的變量代換程序中的變量可通過代換操作取得一個常量,代換操作符為“”。如果在數(shù)字變量前面有一個代換操作符“”,編譯器會將該數(shù)字變量的值轉(zhuǎn)換為十六進制的字符串,并將“”后的數(shù)字變量用該十六進制的字符串代換。如果在邏輯變量前面有一個代換操作符“”,編譯器會
28、將“”后的字符串變量用該字符串變量的值代換。使用示例:GBLS STR1GBLS STR2STR1 SETS“test”STR2 SETS“This is a STR1” ;匯編后,STR2的值為This is a test5. 表達式和運算符在匯編語言程序設計中,也經(jīng)常使用各種表達式,表達式一般由變量、常量、運算符和括號構(gòu)成。常用的表達式有數(shù)字表達式、邏輯表達式和字符串表達式,其運算次序遵循如下的優(yōu)先級:l 優(yōu)先級相同的雙目運算符的運算順序為從左到右;l 相鄰的單目運算符的運算順序為從右到左,且單目運算符的優(yōu)先級高于其他運算符;l 括號運算符的優(yōu)先級最高1)數(shù)字表達式及運算符數(shù)字表達式一般由
29、數(shù)字常量、數(shù)字變量、數(shù)字運算符和括號構(gòu)成。與數(shù)字表達式相關(guān)的運算符如下:l “”、“”、“×”、“”及“MOD”算術(shù)運算符以上的算術(shù)運算任分別代表加、減、乘、除和取余運算。例如,以X和Y表示兩個數(shù)字表達式,則:XY 表示X與Y的和XY 表示X與Y的差X×Y 表示X與Y的乘積XY 表示X與Y的商X:MOD:Y 表示X除以Y的余數(shù)l “ROL”、“ROR”“SHL”及“SHR”移位運算符以X和Y表示兩個數(shù)字表達式,則:X:ROL:Y 表示將X循環(huán)左移Y位X:ROR:Y 表示將X循環(huán)右移Y位X:SHL:Y 表示將X左移Y位X:SHR:Y 表示將X右移Y位l “AND”、“OR”、
30、“NOT”及“EOR”按位邏輯運算符以X和Y表示兩個數(shù)字表達式,則:X:AND:Y 表示將X和Y作邏輯與的操作X:OR:Y 表示將X和Y作邏輯或的操作:NOT:Y 表示將將Y作邏輯非的操作X:EOR:Y 表示將X和Y按位作邏輯異或的操作2) 邏輯表達式及運算符邏輯表達式一般由邏輯量、邏輯運算符和括號構(gòu)成,其表達式的運算結(jié)果為真或假。與邏輯表達式相關(guān)的運算符如下:l “=”、“>”、“<”、“>=”、“/=”“<>”運算符以X和Y表示兩個邏輯表達式,以上的運算符代表運算如下:X=Y 表示X等于YX>Y 表示X大于YX<Y 表示X小于YX>=Y 表示
31、X大于等于YX<=Y 表示X小于等于YX/=Y 表示X不等于YX<>Y 表示X不等于Yl “LAND”、“LOR”、“LNOT”及“LEOR”運算符以X和Y表示兩個邏輯表達式,以上的邏輯運算符代表運算如下:X:LAND:Y 表示將X和Y作邏輯與的操作X:LOR:Y 表示將X和Y作邏輯或的操作:LNOT:Y 表示將將Y作邏輯非的操作X:LEOR:Y 表示將X和Y按位作邏輯異或的操作3) 字符串表達式及運算符字符串表達式一般由字符串常量、字符串變量、運算符和括號構(gòu)成,編譯器所支持的字符串最大長度為512B。常用的字符串表達式相關(guān)的運算符如下:l LEN運算符LEN運算符返回字的長
32、度(字符數(shù)),以X表示字符串表達式,其語法格式如下:LEN:Xl CHR運算符CHR運算符將0255之間的整數(shù)轉(zhuǎn)換為一個字符,以M表示某一個整數(shù),其語法格式如下:CHR:Ml STR運算符STR運算符將一個數(shù)字表達式或邏輯表達式轉(zhuǎn)換為一個字符串。對于數(shù)字表達式,STR運算符將其轉(zhuǎn)換為一個十六進制格式的字符串;對于邏輯表達式,STR運算符將其轉(zhuǎn)換為字符串T或F,其語法格式如下:STR:X其中,X為一個數(shù)字表達式或邏輯表達式。l LEFT運算符LEFT運算符返回某個字符串左端的規(guī)定長度的一個子串,其語法格式如下:X:LEFT:Y其中,X為源字符串,Y為一個整數(shù),表示要返回的字符個數(shù)。l CC運算符
33、CC運算符用于將兩個字符串連接成一個字符串,其語法格式如下:X:CC:Y其中,X為源字符串1,Y為源字符串2,CC運算符將Y連接到X的后面。4) 與寄存器和程序計數(shù)器(PC)相關(guān)的表達式及運算符如下:l BASE運算符BASE運算符返回基于寄存器的表達式中寄存器的編號,其語法格式如下:BASE:X其中,X為與寄存器相關(guān)的表達式。l INDEX運算符INDEX運算符返回基于寄存器的表達式中相對于其基址寄存器的偏移量,其語法格式如下:INDEX:X其中,X為與寄存器相關(guān)的表達式。55) 其他常用運算符l ?運算符?運算符返回基某代碼行所生成的可執(zhí)行代碼的長度,例如:?X返回定義符號X的代碼行所生成
34、的可執(zhí)行代碼的字節(jié)數(shù)。l DEF運算符DEF運算符判斷是否定義某個符號,例如:DEF:X如果符號X已經(jīng)定義,則結(jié)果為真,否則為假。4.3 匯編語言程序設計4.3.1 匯編語言的程序結(jié)構(gòu)在ARM(Thumb)匯編語言程序中,以程序段為單位組織代碼。段是相對獨立的指令或數(shù)據(jù)序列,具有特定的名稱。段可以分為代碼段和數(shù)據(jù)段,代碼段的內(nèi)容為執(zhí)行代碼,數(shù)據(jù)段存放代碼運行時需要用到的數(shù)據(jù)。一個匯編程序至少應該有一個代碼段,當程序較長時,可以分割為多個代碼段和數(shù)據(jù)段,多個段在程序編譯外鏈接時最終形成一個可執(zhí)行的映象文件??蓤?zhí)行映象文件通常由以下幾部分構(gòu)成:l 一個或多個代碼段,代碼段的屬性為可讀/寫。l 零個
35、或我個包含初始化數(shù)據(jù)的數(shù)據(jù)段,數(shù)據(jù)段的屬性為可讀/寫。l 零個或我個不包含初始化數(shù)據(jù)的數(shù)據(jù)段,數(shù)據(jù)段的屬性為可讀/寫。鏈接器系統(tǒng)默認或用戶設定的規(guī)則,將各個段安排在存儲器中的相應位置。因此源程序中段之間的相對位置與可執(zhí)行的映象文件中段的相對位置一般不會相同。以下是一個匯編語言源程序的基本結(jié)構(gòu):AREA Init,CODE,READONLYENTRYStartLDR R0,=0x3FF5000LDR R1,0xFFSTR R1,R0LDR R0,=0x3FF5008LDR R1,0x01STR R1,R0END在匯編語言程序中,用AREA偽指令定義一個段,并說明所定義段的相關(guān)屬性,本例定義一個名
36、為Init的代碼段,屬性為只讀。ENTRY偽指令標識程序的入口點,接下來是指令序列,程序的末尾為END偽指令,該偽指令告訴編譯器源文件的結(jié)束,每一個匯編程序段都必須有一條END偽指令,指示代碼段的結(jié)束。4.3.2 匯編語言的子程序調(diào)用在ARM匯編語言程序中,子程序的調(diào)用一般都是通過BL指令來實現(xiàn)的。在程序中,使用指令“BL子程序名”即可完成子程序的調(diào)用。該指令在執(zhí)行時完成如下操作:將子程序的返回地址存放在鏈接寄存器LR中,同時將程序計數(shù)器PC指向子程序的入口點,當子程序執(zhí)行完畢返回調(diào)用處時,只需要將存放在LR中的返回地址重新復制給程序計數(shù)器PC即可。在調(diào)用子的同時,也可以完成參數(shù)的傳遞和從子程
37、序返回運算的結(jié)果,通常可以使用寄存器R0R3完成。以下是使用BL指令調(diào)用子程序的匯編語言程序的基本結(jié)構(gòu):AREA Init,CODE,READONLYENTRYStartLDR R0,=0x3FF5000LDR R1,0xFFSTR R1,R0LDR R0,=0x3FF5008LDR R1,0x01STR R1,R0BL PRINT_TEXTPRINT_TEXTMOV PC,BLEND4.3.3 宏定義及其作用使用宏定義可以提高程序的可讀性,簡化程序代碼和同步修改。ARM宏定義與標準C語言的#define相似,只在源程序中進行字符的簡單替代。宏定義從MACRO偽指令開始,到MEND結(jié)束,并可以
38、使用參數(shù)。宏首先要定義,然后才能使用。使用時直接書寫宏名,并根據(jù)對應的宏定義格式設置輸入?yún)?shù)或書寫桔等。當源程序被匯編時,匯編器將展開每一個宏調(diào)用,用宏定義代替程序中的宏調(diào)用,并使用實際的參數(shù)值取代宏定義時的形參。下面的例子是一個宏調(diào)用,程序中定義了一個宏CALL,用于調(diào)用子程序,調(diào)用時設置所需要調(diào)用的子程序名Function及兩個入口參數(shù)dat1和dat2。由于宏定義體中使用的是MOV指令,所以dat1參數(shù)只能為8位的立即數(shù)或通用寄存器。MACRO ;宏定義CALLSubfunction Function,dat1,dat2 ;宏名為CALLSubfunction,帶3個參數(shù)LMPORT F
39、unction ;聲明外子程序名MOV R0,dat1 ;設置子程序參數(shù)R0=dat1MOV R1,dat2BL Function ;調(diào)用子程序MENDCALL FADD1,#3,#2 ;宏調(diào)用匯編處理后,宏調(diào)用將被展開,程序如下:IMPORT FADD1MOV R0,#3MOV R1,#2BL FADD14.3.4 數(shù)據(jù)比較跳轉(zhuǎn)匯編程序可以使用CMP指令進行兩個數(shù)的比較,然后根據(jù)比較結(jié)果實現(xiàn)程序的跳轉(zhuǎn),代碼如下:CMP R5,#10 BEQ BRANCH1 ;如果R5為10,則跳轉(zhuǎn)到BRANCH1CMP R1,R2ADDHI R1,R1,#1 ;如果R1>R2,則R1=R1+1ADDLS R1,R1,#2 ;如果R1<=R2,則R1=R1+2ANDS R1,R1,#0x80 ;R1=R1&0x80,并設置相應的標志位BNE WAIT ;如果R1的第7位0,則跳轉(zhuǎn)到WAIT4.3.5 循環(huán)下面的程序代碼為匯編循環(huán)程序的例子,指定了循環(huán)的次數(shù),每循環(huán)一次進行減1操作,并判斷結(jié)果是否為0,如果為0則退出循環(huán)。MOV R0,#10LOOPSUBS R0,R0,#1BEN LOOP4.3. 6 數(shù)據(jù)塊復制可以使用存儲器訪問指令LDM/STM進行讀取和存儲,進行數(shù)據(jù)塊的復制,示例代碼如下: LDR R0,=DATA_DST ;指向數(shù)據(jù)的目標地址 LD
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責。
- 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 金融安全與誠信教育
- 石河子大學《中藥鑒定學實驗一》2021-2022學年第一學期期末試卷
- 石河子大學《藥物分析》2022-2023學年第一學期期末試卷
- 食品安全十三五規(guī)劃
- 石河子大學《計算機組織與結(jié)構(gòu)》2022-2023學年期末試卷
- 石河子大學《兒科學與兒童保健學見習》2021-2022學年第一學期期末試卷
- 沈陽理工大學《三維工程軟件》2023-2024學年第一學期期末試卷
- 沈陽理工大學《建筑結(jié)構(gòu)》2022-2023學年第一學期期末試卷
- 2018年四川內(nèi)江中考滿分作文《我心中的英雄》
- 沈陽理工大學《含能材料》2021-2022學年第一學期期末試卷
- 2024年安能物流合作加盟協(xié)議版
- 質(zhì)量管理體系過程方法和風險思維專業(yè)解讀與應用之7:5 領(lǐng)導作用-5.3組織的崗位、職責和權(quán)限(雷澤佳編制-2024B1)
- 地面找平專項施工方案
- 初三化學-水的凈化省公開課獲獎課件說課比賽一等獎課件
- 2024-2030年中國財稅服務行業(yè)市場深度調(diào)研及發(fā)展前景與投資研究報告
- 第二次月考卷-2024-2025學年統(tǒng)編版語文六年級上冊
- 申論國家公務員考試試題與參考答案
- 亂扔垃圾的課件
- 2024-2030年中國安全校車市場發(fā)展分析及市場趨勢與投資方向研究報告
- 數(shù)字孿生水利項目建設可行性研究報告
- 北京市房山區(qū)2023-2024學年高二上學期期中地理試題 含解析
評論
0/150
提交評論