【正文】
? 循環(huán)程序設(shè)計(jì)( 3) 設(shè) x為 R0, y為 R1( x、 y均為無符號整數(shù)),匯編語言程序段如下: 例 28 編寫循環(huán)語句實(shí)現(xiàn)數(shù)據(jù)塊復(fù)制。 i 10 。 在 C語言中, for和 while語句可以實(shí)現(xiàn)這兩種循環(huán)。 ■ 循環(huán)體:就是要求重復(fù)執(zhí)行的程序段部分。 ? 分支程序設(shè)計(jì)( 2) 圖 分支流程圖 設(shè) R0保存變量 x的值, R1保存變量 y的值, R2保存變量 z的值( x、 y、 z均為無符號整數(shù)),對應(yīng)實(shí)現(xiàn)的匯編程序見程序清單 。 C語言程序如下(分支流程圖如圖 ): 圖 分支流程圖 int x=76。 程序中首先讀取數(shù)組的第 1項(xiàng)數(shù)據(jù),然后讀取第 5項(xiàng)數(shù)據(jù),之后將結(jié)果相加,最后保存結(jié)果,整個(gè)流程是順序執(zhí)行的,如圖 。 本小節(jié)將介紹順序 、 分支 、 循環(huán)和子程序這 4種結(jié)構(gòu)。 這樣的源文件類似于C語言中的頭文件, GET/INCLUDE不能用于包含目標(biāo)文件,包含目標(biāo)文件則需要使用 INCBIN偽指令。 例 22 導(dǎo)入標(biāo)號 InitStack和 Vectors。 偽指令格式如下: 其中,標(biāo)號為要聲明的符號名稱。 EXPORT 標(biāo)號 [, WEAK] GLOBAL 標(biāo)號 [, WEAK] ? 雜項(xiàng)偽指令( 3) 例 21 定義全局標(biāo)號 InitStack和 Vectors。 GLOBAL與 EXPORT相同。 ■ 文件包含偽指令: GET、 INCLUDE。 WHILE logical_expr ;指令或偽指令代碼段 WEND ? 匯編控制偽指令( 9) 例 20 重復(fù)匯編舉例。 . . .I F { C O N F I G } = 1 6 B N E _ _ r t _ u d iv _ 1 L D R R 0 , = _ _ r t _ d iv 0 B X R 0E L S E B E Q _ _ r t _ d iv 0E N D I F ? 匯編控制偽指令( 8) ( 3)重復(fù)匯編偽指令 WHILE和 WEND: WHILE和 WEND偽指令用于根據(jù)條件重復(fù)匯編相同的或幾乎相同的一段源程序。若條件成立,則代碼段 1落在匯編源程序中有效。倒數(shù)第二條語句是宏調(diào)用語句,編譯后該條語句會(huì)展開。 ? 匯編控制偽指令( 4) 宏與子程序的區(qū)別,在于調(diào)用宏時(shí)編譯程序會(huì)在調(diào)用處插入宏的程序段,有多少次調(diào)用就會(huì)插入多少宏的程序段;而調(diào)用子程序不增加新的程序段。 在其他程序中可以調(diào)用宏來完成某個(gè)功能。 ■ 參數(shù):宏指令的參數(shù)。指令格式如下: M A C R O[ $ 標(biāo) 號 ] 宏 名 [ $ 參 數(shù) ] ; 參 數(shù) 可 以 有 多 個(gè) 語 句 段 M E X I T 語 句 段M E N D ? 匯編控制偽指令( 3) 宏定義指令格式說明如下: ■ 標(biāo)號:是可選項(xiàng)。 ? 匯編控制偽指令( 2) ( 1)宏定義偽指令 MACRO和 MEND: 宏定義偽指令包括 MACRO、 MEND、 MEXIT。 L D R P C , R e s e t A d d r L D R P C , U n d e f i n e A d d r . . .R e s e t A d d r D C D R e s e t ; R e s e t A d d r 變 量 保 存 R e s e t 標(biāo) 號 的 地 址U n d e f i n e A d d r D C D U n d e f i n e d ; U n d e f i n e A d d r 變 量 保 存 U n d e f i n e d 標(biāo) 號 的 地 址 . . .R e s e t . . .U n d e f i n e d . . . ? 匯編控制偽指令( 1) 匯編控制偽指令用于條件匯編、宏定義、重復(fù)匯編控制等。圖 ,其中DCB偽指令定義的每個(gè)數(shù)據(jù)占用一個(gè)字節(jié)空間, DCW偽指令定義的每個(gè)數(shù)據(jù)占用兩個(gè)字節(jié)空間, DCD偽指令定義的每個(gè)數(shù)據(jù)占用 4個(gè)字節(jié)空間。 ■ DCD分配一段字的內(nèi)存單元,其后的每個(gè)操作數(shù)都占有 4個(gè)字節(jié),操作數(shù)可以是 32位的數(shù)字表達(dá)式,也可以是程序中的標(biāo)號(因?yàn)槌绦蛑械臉?biāo)號代表地址,也是32位二進(jìn)制數(shù)值)。 這一類偽指令的格式是: 其中標(biāo)號 label字段是可有可無的,它表示分配的內(nèi)存起始地址,作用與指令語句前的標(biāo)號相同。 偽指令格式如下: 其中, label為內(nèi)存塊起始地址標(biāo)號, expr為所要分配的內(nèi)存字節(jié)數(shù)。 例 13 MAP和 FIELD偽指令的使用。 FIELD也可用? ?代替。 MAP偽指令通常與 FIELD偽指令配合使用來定義結(jié)構(gòu)化的內(nèi)存表。 MAP也可用? ^?代替。 LTORGLDR R0, =0xFFFF5678 ;LDR偽指令,裝載0xFFFF5678給R0ADD R1, R1, R0MOV PC, LRLTORG ;聲明文字池,此地址存儲(chǔ)程序中用到的數(shù)據(jù)0xFFFF5678... ;其他代碼 ? 數(shù)據(jù)定義偽指令( 3) LTORG偽指令常放在無條件跳轉(zhuǎn)指令之后,或者子程序返回指令之后,這樣處理器就不會(huì)錯(cuò)誤地將文字池中的數(shù)據(jù)當(dāng)作指令來執(zhí)行。 ■ 分配一段字的內(nèi)存單元,并用指定的數(shù)據(jù)初始化:DCD。 ■ 定義結(jié)構(gòu)化內(nèi)存表中的一個(gè)數(shù)據(jù)域: FIELD。 ALIGN {表達(dá)式{, 偏移量} ? 數(shù)據(jù)定義偽指令( 1) 數(shù)據(jù)定義偽指令用于數(shù)據(jù)表定義、文字池定義、數(shù)據(jù)空間分配等,同時(shí)也可完成已分配存儲(chǔ)單元的初始化。 如果偽指令中沒有指定表達(dá)式,則編譯器會(huì)將當(dāng)前位臵對齊到下一個(gè)字的位臵 。 例 10 聲明了代碼段 Example1,只讀,并且 4字節(jié)對齊。 ■ NOINIT指定本數(shù)據(jù)段僅僅保留了內(nèi)存單元,而沒有將各個(gè)初始值寫入內(nèi)存單元,或者將內(nèi)存單元值初始化為 0。 ■ COMMON定義一個(gè)通用段。 ■ CODE為定義代碼段。對于代碼段, expr不能為 0或 1。如果該名稱是以數(shù)據(jù)開頭的,則該名稱必須用? |?括起來。 ? 段及段屬性定義偽指令( 3) 下面介紹稍微復(fù)雜的 AREA偽指令和 ALIGN偽指令。 CODE16和 CODE32偽指令只是指示匯編編譯器后面的指令的類型,偽指令本身并不進(jìn)行程序狀態(tài)切換。一個(gè)程序(可以包含多個(gè)源文件)至少要有一個(gè) ENTRY,可以有多個(gè) ENTRY,但一個(gè)源文件中最多只有一個(gè) ENTRY。 ■ CODE32:指明本段為 32位 ARM代碼。 ■ END:整個(gè)文件結(jié)束。 expr_a為賦值的常數(shù); expr_l為邏輯值,即 {TRUE}或 {FALSE}; expr_s為賦值的字符串。 ■ SETA偽指令用于給一個(gè)全局或局部的算術(shù)變量賦值。 variable是定義的變量名,其數(shù)據(jù)類型和作用范圍由變量聲明偽指令來確定,但變量名在其作用內(nèi)必須唯一。其中: ■ GBLA、 LCLA偽指令用于聲明一個(gè)數(shù)字變量,并將其初始化為 0。 例 5 EQU偽指令的使用。 符號定義偽指令包括 EQU偽指令 、 變量聲明偽指令 、 變量賦值偽指令 。 ? 偽指令語句( 2) ■ 數(shù)據(jù)定義偽指令。把它們和指令集一起介紹是因?yàn)樗鼈冊趨R編時(shí)會(huì)被合適的機(jī)器指令代替,實(shí)現(xiàn)真正機(jī)器指令操作。偽指令不像機(jī)器指令那樣在處理器運(yùn)行期間由機(jī)器執(zhí)行,而是在對源程序進(jìn)行匯編期間由匯編工具處理的操作,它們可以完成如符號定義、數(shù)據(jù)定義、分配存儲(chǔ)區(qū)、指示程序開始結(jié)束等功能。 按照變量的作用范圍可分為全局變量和局部變量;按照變量的數(shù)值類型可分為數(shù)字變量、字符變量和邏輯變量。 T_bit EQU 0x20 ;定義數(shù)字常量T_bit,其值為0x20PLCON EQU 0xE01FC080 ;定義PLCON,值為0xE01FC080 ? 語句行的符號( 6) ( 3)變量名: 變量是指存放在存儲(chǔ)單元的操作數(shù),并且它的值可以改變。 為了程序書寫的方便,可以用一個(gè)標(biāo)識(shí)符來代表一個(gè)常量,稱這個(gè)標(biāo)識(shí)符為符號常量,即標(biāo)識(shí)符形式的常量。如果需要包含雙引號或? $?,必須使用??或? $$?代替。 ... ;...表示省略的程序 B START ;程序跳轉(zhuǎn)到START標(biāo)號處 ...START ;START標(biāo)號,這是一個(gè)基于PC的段內(nèi)標(biāo)號 ... ? 語句行的符號( 4) ( 2)符號常量: 在程序運(yùn)行過程中,其值不能被改變的量稱為常量。這種標(biāo)號在匯編時(shí)被處理成寄存器的值加上或減去一個(gè)數(shù)字常量。根據(jù)標(biāo)號的生成方式可以分為以下 3種: ■ 基于 PC的標(biāo)號:該標(biāo)號是位于目標(biāo)指令前的標(biāo)號或程序中的數(shù)據(jù)定義偽指令前的標(biāo)號。 符號可以代表地址、數(shù)值、變量。 ■ 符號區(qū)分大小寫,且所有字符都是有意義的。符號分為兩大類:指令助記符和用戶定義符。注釋內(nèi)容由?;?開始到此行結(jié)束,注釋可以在一行的頂格書寫。在書寫ARM匯編程序時(shí),需要注意以下 3點(diǎn): ■ 標(biāo)號必須在一行的頂格書寫,其后面不要加?:?,對于變量的設(shè)臵、常量的定義,其標(biāo)識(shí)符必須在一行的頂格書寫;而所有指令均不能頂格書寫。 ■ 指示性語句:匯編程序并不把它們翻譯成機(jī)器代碼,只是用來指示、引導(dǎo)匯編程序在匯編時(shí)進(jìn)行一些操作。 ? ARM匯編程序的書寫格式( 1) ARM匯編源程序是由若干段組成的,而一個(gè)段又是由若干個(gè)語句行組成。源程序的一般格式為: AREA name1, attr ;聲明特定的段標(biāo)號 語句1 ;語句