嵌入式系統(tǒng)第4章_第1頁(yè)
嵌入式系統(tǒng)第4章_第2頁(yè)
嵌入式系統(tǒng)第4章_第3頁(yè)
嵌入式系統(tǒng)第4章_第4頁(yè)
嵌入式系統(tǒng)第4章_第5頁(yè)
已閱讀5頁(yè),還剩129頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

1、嵌入式系統(tǒng)原理及應(yīng)用教程嵌入式系統(tǒng)原理及應(yīng)用教程主講內(nèi)容主講內(nèi)容第第1章章 嵌入式系統(tǒng)概述嵌入式系統(tǒng)概述第第2章章 ARM微處理器概述與編程模型微處理器概述與編程模型第第3章章 ARM9指令系統(tǒng)指令系統(tǒng)第第4章章 嵌入式程序設(shè)計(jì)基礎(chǔ)嵌入式程序設(shè)計(jì)基礎(chǔ)第第5章章 嵌入式內(nèi)部可編程模塊嵌入式內(nèi)部可編程模塊第第6章章 嵌入式接口技術(shù)應(yīng)用嵌入式接口技術(shù)應(yīng)用第第7章章 軟件開發(fā)環(huán)境軟件開發(fā)環(huán)境第第4章章 嵌入式程序設(shè)計(jì)基礎(chǔ)嵌入式程序設(shè)計(jì)基礎(chǔ)u基于基于ARM的編譯器一般都支持匯編語言的程序設(shè)的編譯器一般都支持匯編語言的程序設(shè)計(jì)、計(jì)、C/C+語言的程序設(shè)計(jì)及兩者的混合編程。語言的程序設(shè)計(jì)及兩者的混合編程。u

2、本章介紹本章介紹ARM的嵌入式程序的基礎(chǔ)知識(shí)的嵌入式程序的基礎(chǔ)知識(shí)u偽指令偽指令u匯編語言的語句格式匯編語言的語句格式u匯編語言匯編語言u(píng)C/C+語言的混合編程語言的混合編程.4.1 偽指令偽指令u在在ARM匯編語言程序里,有一些特殊指令助記符,匯編語言程序里,有一些特殊指令助記符,這些助記符與指令系統(tǒng)的助記符不同,沒有相對(duì)這些助記符與指令系統(tǒng)的助記符不同,沒有相對(duì)應(yīng)的操作碼,通常稱這些特殊指令助記符為應(yīng)的操作碼,通常稱這些特殊指令助記符為偽指?jìng)沃噶盍睿麄兯瓿傻牟僮鞣Q為偽操作。,他們所完成的操作稱為偽操作。u偽指令在源程序中的偽指令在源程序中的作用作用是既要把正常的程序用是既要把正常的程序

3、用指令表達(dá)給計(jì)算機(jī)以外,又要把程序設(shè)計(jì)者的意指令表達(dá)給計(jì)算機(jī)以外,又要把程序設(shè)計(jì)者的意圖表達(dá)給編譯器圖表達(dá)給編譯器. 例如:例如:要告訴編譯器程序段的開始和結(jié)束,需要告訴編譯器程序段的開始和結(jié)束,需要定義數(shù)據(jù)等要定義數(shù)據(jù)等.u在在ARM的匯編程序中,我們把偽指令分為三部分的匯編程序中,我們把偽指令分為三部分介紹介紹:l通用偽指令通用偽指令 l與與ARM指令相關(guān)的偽指令指令相關(guān)的偽指令l與與Thumb指令相關(guān)的偽指令指令相關(guān)的偽指令 4.1 偽指令偽指令4.1.1 通用偽指令通用偽指令 通用偽指令包括通用偽指令包括:u符號(hào)定義偽指令符號(hào)定義偽指令u數(shù)據(jù)定義偽指令數(shù)據(jù)定義偽指令u匯編控制偽指令匯編

4、控制偽指令u及其他一些常用偽指令等。及其他一些常用偽指令等。4.1.1 通用偽指令通用偽指令1.符號(hào)定義偽指令符號(hào)定義偽指令 符號(hào)定義偽指令用于聲明符號(hào)定義偽指令用于聲明ARM匯編程序中的變量、對(duì)變量匯編程序中的變量、對(duì)變量賦值以及定義寄存器的名稱等操作。賦值以及定義寄存器的名稱等操作。常見的符號(hào)定義偽指令有如下幾種:常見的符號(hào)定義偽指令有如下幾種:(1)GBLA、GBLL和和GBLS語法格式:語法格式: GBLA(GBLL或或GBLS) 全局變量名全局變量名 GBLA、GBLL和和GBLS偽指令是聲明全局變量的偽指令,偽指令是聲明全局變量的偽指令,用于定義一個(gè)用于定義一個(gè)ARM程序中的全局變

5、量,并將其初始化。程序中的全局變量,并將其初始化。4.1.1 通用偽指令通用偽指令其中:其中:uGBLA用于聲明一個(gè)全局的數(shù)字變量,并初始化為用于聲明一個(gè)全局的數(shù)字變量,并初始化為0;uGBLL偽指令用于聲明一個(gè)全局的邏輯變量,并初始化為偽指令用于聲明一個(gè)全局的邏輯變量,并初始化為F(假);(假);uGBLS偽指令用于聲明一個(gè)全局的字符串變量,并初始化為偽指令用于聲明一個(gè)全局的字符串變量,并初始化為空;對(duì)于空;對(duì)于全局變量全局變量來說,變量名在源程序中必須是唯一的。來說,變量名在源程序中必須是唯一的。1.符號(hào)定義偽指令符號(hào)定義偽指令 符號(hào)定義偽指令用于聲明符號(hào)定義偽指令用于聲明ARM匯編程序中

6、的變量、匯編程序中的變量、對(duì)變量賦值以及定義寄存器的名稱等操作。對(duì)變量賦值以及定義寄存器的名稱等操作。常見的符號(hào)定義偽指令有如下幾種:常見的符號(hào)定義偽指令有如下幾種:(1)GBLA、GBLL和和GBLS4.1.1 通用偽指令通用偽指令指令示例:指令示例:GBLADATE1;聲明一個(gè)全局?jǐn)?shù)字變量;聲明一個(gè)全局?jǐn)?shù)字變量DATE1GBLLDATE1;聲明一個(gè)全局邏輯變量;聲明一個(gè)全局邏輯變量DATE2GBLSDATA3 ;聲明一個(gè)全局的字符串變量;聲明一個(gè)全局的字符串變量DATE3DATE3SETS“Testing”;將該變量賦值為;將該變量賦值為“Testing”能不用盡量不用能不用盡量不用4.1

7、.1 通用偽指令通用偽指令(2)LCLA、LCLL和和LCLS語法格式:語法格式: LCLA(LCLL或或LCLS)局部變量名局部變量名 LCLA、LCLL和和LCLS 偽指令是聲明局部變量偽指令,偽指令是聲明局部變量偽指令,用于定義一個(gè)用于定義一個(gè)ARM程序中的局部變量,并將其初始化。程序中的局部變量,并將其初始化。其中:其中:uLCLA用于聲明一個(gè)局部的用于聲明一個(gè)局部的數(shù)字變量數(shù)字變量,并初始化為,并初始化為0;uLCLL用于聲明一個(gè)局部的用于聲明一個(gè)局部的邏輯變量邏輯變量,并初始化為,并初始化為F(假);(假);uLCLS用于聲明一個(gè)用于聲明一個(gè)局部的字符串變量局部的字符串變量,并初始

8、化為空。,并初始化為空。對(duì)于局部變量來說,變量名在使用的范圍內(nèi)必須是唯一對(duì)于局部變量來說,變量名在使用的范圍內(nèi)必須是唯一的,范圍限制在定義這個(gè)變量的宏指令程序段內(nèi)。的,范圍限制在定義這個(gè)變量的宏指令程序段內(nèi)。4.1.1 通用偽指令通用偽指令指令示例:指令示例:LCLADATE4;聲明一個(gè)局部數(shù)字變量;聲明一個(gè)局部數(shù)字變量DATE4LCLLDATE5;聲明一個(gè)局部的邏輯變量;聲明一個(gè)局部的邏輯變量DATE5DATA4SETL 0 x10;為變量;為變量DATE4賦值為賦值為0 x10LCLSDATA6;聲明一個(gè)局部的字符串變量;聲明一個(gè)局部的字符串變量DATA64.1.1 通用偽指令通用偽指令(

9、3)SETA、SETL和和SETS語法格式:語法格式:變量名變量名 SETA(SETL或或SETS)表達(dá)式)表達(dá)式 SETA、SETL、SETS是是變量賦值偽指令,用于給一變量賦值偽指令,用于給一個(gè)已經(jīng)定義的全局變量或局部變量賦值個(gè)已經(jīng)定義的全局變量或局部變量賦值。其中:其中:uSETA用于給一個(gè)數(shù)學(xué)變量賦值;用于給一個(gè)數(shù)學(xué)變量賦值;uSETL用于給一個(gè)邏輯變量賦值;用于給一個(gè)邏輯變量賦值;uSETS用于給一個(gè)字符串變量賦值;用于給一個(gè)字符串變量賦值;4.1.1 通用偽指令通用偽指令指令示例:指令示例:GBLA EXAMP1;先聲明一個(gè)全局?jǐn)?shù)字變量;先聲明一個(gè)全局?jǐn)?shù)字變量EXAMP1LCLL

10、EXAMP2;聲明一個(gè)局部的邏輯變量;聲明一個(gè)局部的邏輯變量EXAMP2EXAMP1 SETLTRUE;將變量;將變量EXAMP1賦值為賦值為TRUEGBLA EXAMP3;先聲明一個(gè)全局字符串變量;先聲明一個(gè)全局字符串變量EXAMP3 EXAMP3 SETS“string”;將變量;將變量EXAMP3賦值為賦值為string4.1.1 通用偽指令通用偽指令(4)RLIST語法格式:語法格式: 名稱名稱 RLIST 寄存器列表寄存器列表 RLIST偽指令是偽指令是定義通用寄存列表偽指令定義通用寄存列表偽指令,通用寄存,通用寄存器列表定義器列表定義主要應(yīng)用在堆棧操作或多寄存器傳送中主要應(yīng)用在堆棧

11、操作或多寄存器傳送中,即使用該偽指令定義的名稱可在即使用該偽指令定義的名稱可在ARM指令指令LDM/STM中使用。中使用。 在在LDM/STM指令中指令中,列表中的寄存器訪問次序?yàn)楦斜碇械募拇嫫髟L問次序?yàn)楦鶕?jù)寄存器的編號(hào)據(jù)寄存器的編號(hào)由低到高由低到高,而與,而與列表中的寄存器排列列表中的寄存器排列次序無關(guān)。次序無關(guān)。4.1.1 通用偽指令通用偽指令指令示例:指令示例:RegListRLISTR0-R5,R8 ;定義寄存器列表;定義寄存器列表R0-R5,R8 為為RegList在程序中使用:在程序中使用:STMFD SP!,RegList;存儲(chǔ)列表;存儲(chǔ)列表到堆棧到堆棧LDMIA R5,Re

12、gList;加載列表;加載列表 4.1.1 通用偽指令通用偽指令2.數(shù)據(jù)定義偽指令數(shù)據(jù)定義偽指令 數(shù)據(jù)定義偽指令一般用于為特定的數(shù)據(jù)分配存儲(chǔ)單元,數(shù)據(jù)定義偽指令一般用于為特定的數(shù)據(jù)分配存儲(chǔ)單元,同時(shí)可完成已分配存儲(chǔ)單元的初始化。常見的數(shù)據(jù)定同時(shí)可完成已分配存儲(chǔ)單元的初始化。常見的數(shù)據(jù)定義偽指令有如下幾種:義偽指令有如下幾種:(1)DCB語法格式:語法格式: 標(biāo)號(hào)標(biāo)號(hào) DCB表達(dá)式表達(dá)式 DCB偽指令是偽指令是字節(jié)分配內(nèi)存單元字節(jié)分配內(nèi)存單元偽指令,用來分配偽指令,用來分配一片連續(xù)的字節(jié)存儲(chǔ)單元一片連續(xù)的字節(jié)存儲(chǔ)單元并用偽指令中并用偽指令中指定的數(shù)值指定的數(shù)值或或字符初始化。其中,數(shù)值范圍為字符

13、初始化。其中,數(shù)值范圍為0255,DCB也可用也可用“=”代替。代替。4.1.1 通用偽指令通用偽指令指令示例:指令示例:String DCB “This is a test!”;分配一片連續(xù)的字節(jié)存儲(chǔ)單元并初始化。;分配一片連續(xù)的字節(jié)存儲(chǔ)單元并初始化。DATA2 DCB 15,25,62,00;為數(shù)字常量;為數(shù)字常量15,25,62,00分片內(nèi)存單元分片內(nèi)存單元4.1.1 通用偽指令通用偽指令(2)DCW(或(或DCWU)語法格式:語法格式: 標(biāo)號(hào)標(biāo)號(hào) DCW(或(或DCWU)表達(dá)式)表達(dá)式 DCW(或(或DCWU)偽指令)偽指令是為半字分配內(nèi)存單是為半字分配內(nèi)存單元元,其中,表達(dá)式可以為程

14、序標(biāo)號(hào)或數(shù)字表達(dá)式。,其中,表達(dá)式可以為程序標(biāo)號(hào)或數(shù)字表達(dá)式。 偽指令偽指令DCW用于為用于為半字分配一段半字對(duì)準(zhǔn)半字分配一段半字對(duì)準(zhǔn)的內(nèi)存的內(nèi)存單元,并用指定的數(shù)據(jù)初始化;偽指令單元,并用指定的數(shù)據(jù)初始化;偽指令DCWU用于為用于為半字分配一段可以非半字對(duì)準(zhǔn)半字分配一段可以非半字對(duì)準(zhǔn)的內(nèi)存單元,并用指定的內(nèi)存單元,并用指定的數(shù)據(jù)初始化。的數(shù)據(jù)初始化。4.1.1 通用偽指令通用偽指令指令示例:指令示例:DATA1 DCW 1,2,3 ;分配一片連續(xù)的半字存儲(chǔ)單元并初始化為;分配一片連續(xù)的半字存儲(chǔ)單元并初始化為1,2,3。DATA2 DCWU 45,0 x2a*0 x2a ;分配一片非半字對(duì)準(zhǔn)存

15、儲(chǔ)單元并初始化。;分配一片非半字對(duì)準(zhǔn)存儲(chǔ)單元并初始化。4.1.1 通用偽指令通用偽指令(3)DCD(或(或DCDU)語法格式:語法格式: 標(biāo)號(hào)標(biāo)號(hào) DCD(或(或DCDU)表達(dá)式表達(dá)式 DCD(或(或DCDU)偽指令是為字分配內(nèi)存單元偽)偽指令是為字分配內(nèi)存單元偽指令,其中,表達(dá)式可以為程序標(biāo)號(hào)或數(shù)字表達(dá)式。指令,其中,表達(dá)式可以為程序標(biāo)號(hào)或數(shù)字表達(dá)式。DCD也可用也可用“&”代替。代替。 偽指令偽指令DCD用來為字分配一段對(duì)準(zhǔn)的內(nèi)存單元,用來為字分配一段對(duì)準(zhǔn)的內(nèi)存單元,并用指定的數(shù)值或標(biāo)號(hào)初始化;偽指令并用指定的數(shù)值或標(biāo)號(hào)初始化;偽指令DCDU用來為用來為字分配一段可以非對(duì)準(zhǔn)的內(nèi)存單

16、元,并用指定的數(shù)值字分配一段可以非對(duì)準(zhǔn)的內(nèi)存單元,并用指定的數(shù)值或標(biāo)號(hào)初始化?;驑?biāo)號(hào)初始化。4.1.1 通用偽指令通用偽指令指令示例:指令示例:DATA1 DCD 4,5,6;分配一片連續(xù)的字存儲(chǔ)單元并初始化。;分配一片連續(xù)的字存儲(chǔ)單元并初始化。DATA2 DCDU LOOP ;為為L(zhǎng)OOP標(biāo)號(hào)的地址值分配標(biāo)號(hào)的地址值分配一個(gè)內(nèi)存單元。一個(gè)內(nèi)存單元。4.1.1 通用偽指令通用偽指令(4)DCFD(或(或DCFDU)和)和DCFS(或(或DCFSU)語法格式:語法格式: 標(biāo)號(hào)標(biāo)號(hào) 偽指令偽指令 表達(dá)式表達(dá)式uDCFD(或(或DCFDU)和)和DCFS(或(或DCFSU)都是為)都是為浮點(diǎn)數(shù)分配浮

17、點(diǎn)數(shù)分配內(nèi)存單元的偽指令。內(nèi)存單元的偽指令。uDCFD用于為用于為雙精度的浮點(diǎn)數(shù)分配一段字對(duì)準(zhǔn)的內(nèi)存單元雙精度的浮點(diǎn)數(shù)分配一段字對(duì)準(zhǔn)的內(nèi)存單元,并,并用指定的數(shù)據(jù)初始化,每個(gè)雙精度的浮點(diǎn)數(shù)占兩個(gè)字單元;用指定的數(shù)據(jù)初始化,每個(gè)雙精度的浮點(diǎn)數(shù)占兩個(gè)字單元; DCFDU用于為雙精度的浮點(diǎn)數(shù)分配一段非字對(duì)準(zhǔn)的內(nèi)存單元,用于為雙精度的浮點(diǎn)數(shù)分配一段非字對(duì)準(zhǔn)的內(nèi)存單元,并用指定的數(shù)據(jù)初始化,每個(gè)雙精度的浮點(diǎn)數(shù)占兩個(gè)字單元;并用指定的數(shù)據(jù)初始化,每個(gè)雙精度的浮點(diǎn)數(shù)占兩個(gè)字單元;uDCFS用于為用于為單精度的浮點(diǎn)數(shù)分配一段字對(duì)準(zhǔn)的內(nèi)存單元單精度的浮點(diǎn)數(shù)分配一段字對(duì)準(zhǔn)的內(nèi)存單元,并,并用指定的數(shù)據(jù)初始化,每個(gè)

18、單精度的浮點(diǎn)數(shù)占一個(gè)字單元;用指定的數(shù)據(jù)初始化,每個(gè)單精度的浮點(diǎn)數(shù)占一個(gè)字單元;uDCFSU用于為單精度的浮點(diǎn)數(shù)分配一段非字對(duì)準(zhǔn)的內(nèi)存單元,用于為單精度的浮點(diǎn)數(shù)分配一段非字對(duì)準(zhǔn)的內(nèi)存單元,并用指定的數(shù)據(jù)初始化,每個(gè)單精度的浮點(diǎn)數(shù)占一個(gè)字單元。并用指定的數(shù)據(jù)初始化,每個(gè)單精度的浮點(diǎn)數(shù)占一個(gè)字單元。4.1.1 通用偽指令通用偽指令指令示例:指令示例:FLO1 DCFD2E115,-5E7;分配一段字對(duì)準(zhǔn)存儲(chǔ)單元并初始化為指定的雙精度數(shù);分配一段字對(duì)準(zhǔn)存儲(chǔ)單元并初始化為指定的雙精度數(shù)為為2E115,-5E7。FLO2 DCFDU22,1E2;分配一段非字對(duì)準(zhǔn)存儲(chǔ)單元并初始化為指定的雙精度;分配一段非

19、字對(duì)準(zhǔn)存儲(chǔ)單元并初始化為指定的雙精度數(shù)為數(shù)為22,1E2。FLO3 DCFS2E5,-5E7;分配一段非字對(duì)準(zhǔn)存儲(chǔ)單元并初始化為指定的單精度;分配一段非字對(duì)準(zhǔn)存儲(chǔ)單元并初始化為指定的單精度數(shù)為數(shù)為2E5,-5E-7。4.1.1 通用偽指令通用偽指令(5)DCQ(或或DCQU)語法格式:語法格式: 標(biāo)號(hào)標(biāo)號(hào) DCQ(或(或DCQU)表達(dá)式)表達(dá)式 DCQ(或(或DCQU)偽指令是為)偽指令是為雙字分配內(nèi)存單元雙字分配內(nèi)存單元的偽指令。的偽指令。 偽指令偽指令DCQ用于為雙字分配一段字對(duì)準(zhǔn)的內(nèi)存單元,并用指用于為雙字分配一段字對(duì)準(zhǔn)的內(nèi)存單元,并用指定的數(shù)據(jù)初始化;偽指令定的數(shù)據(jù)初始化;偽指令DCQ

20、U用于為雙字分配一段可以非用于為雙字分配一段可以非字對(duì)準(zhǔn)的內(nèi)存單元,并用指定的數(shù)據(jù)初始化。字對(duì)準(zhǔn)的內(nèi)存單元,并用指定的數(shù)據(jù)初始化。指令示例:指令示例: DATA1DCQ 100 ;分配一片連續(xù)的存儲(chǔ)單元并初始化為指定的值。;分配一片連續(xù)的存儲(chǔ)單元并初始化為指定的值。4.1.1 通用偽指令通用偽指令(6)MAP和和FILED語法格式:語法格式:MAP 表達(dá)式,表達(dá)式,基址寄存器基址寄存器 標(biāo)號(hào)標(biāo)號(hào) FIELD 表明數(shù)據(jù)字節(jié)數(shù)的數(shù)值表明數(shù)據(jù)字節(jié)數(shù)的數(shù)值MAP和和FILED是內(nèi)存表定義偽指令。是內(nèi)存表定義偽指令。u偽指令偽指令MAP用于定義一個(gè)結(jié)構(gòu)化的內(nèi)存表的首地址用于定義一個(gè)結(jié)構(gòu)化的內(nèi)存表的首地址

21、,MAP也可用也可用“”代替;代替;u偽指令偽指令FIELD用于定義內(nèi)存表中的數(shù)據(jù)的長(zhǎng)度用于定義內(nèi)存表中的數(shù)據(jù)的長(zhǎng)度。FILED也可用也可用“#”代替。代替。4.1.1 通用偽指令通用偽指令u表達(dá)式可以為程序中的標(biāo)號(hào)或數(shù)學(xué)表達(dá)式,基址寄存表達(dá)式可以為程序中的標(biāo)號(hào)或數(shù)學(xué)表達(dá)式,基址寄存器為可選項(xiàng),器為可選項(xiàng),當(dāng)基址寄存器選項(xiàng)不存在時(shí),表達(dá)式的當(dāng)基址寄存器選項(xiàng)不存在時(shí),表達(dá)式的值即為內(nèi)存表的首地址,值即為內(nèi)存表的首地址,當(dāng)該選項(xiàng)存在時(shí),內(nèi)存表的當(dāng)該選項(xiàng)存在時(shí),內(nèi)存表的首地址為表達(dá)式的值與基址寄存器的和。首地址為表達(dá)式的值與基址寄存器的和。u注意注意MAP和和FIELD偽指令僅用于定義數(shù)據(jù)結(jié)構(gòu),并偽

22、指令僅用于定義數(shù)據(jù)結(jié)構(gòu),并不實(shí)際分配存儲(chǔ)單元。不實(shí)際分配存儲(chǔ)單元。4.1.1 通用偽指令通用偽指令指令示例:指令示例:MAP0 x10,R1;定義內(nèi)存表首地址的值為;定義內(nèi)存表首地址的值為R1+0 x10。DATA1FIELD4;為數(shù)據(jù);為數(shù)據(jù)DATA1定義定義4字節(jié)長(zhǎng)度字節(jié)長(zhǎng)度DATA2FIELD16;為數(shù)據(jù);為數(shù)據(jù)DATA1定義定義16字節(jié)長(zhǎng)度字節(jié)長(zhǎng)度4.1.1 通用偽指令通用偽指令(7)SPACE語法格式:語法格式: 標(biāo)號(hào)標(biāo)號(hào)SPACE 分配的內(nèi)存單元字節(jié)數(shù)分配的內(nèi)存單元字節(jié)數(shù) SPACE偽指令是內(nèi)存單元分配偽指令,用于分配一偽指令是內(nèi)存單元分配偽指令,用于分配一片連續(xù)的存儲(chǔ)區(qū)域并初始化

23、為片連續(xù)的存儲(chǔ)區(qū)域并初始化為0,SPACE也可用也可用“”代替。代替。指令示例:指令示例: DATASPA SPACE 100;為;為DATASPA分配分配100個(gè)存儲(chǔ)單元個(gè)存儲(chǔ)單元;并初始化為;并初始化為04.1.1 通用偽指令通用偽指令3.匯編控制偽指令匯編控制偽指令匯編控制偽指令用于控制匯編程序的執(zhí)行流程匯編控制偽指令用于控制匯編程序的執(zhí)行流程,常用的,常用的匯編控制偽指令包括以下幾條:匯編控制偽指令包括以下幾條:(1)MACRO、MEND和和MEXIT語法格式:語法格式:MACRO$標(biāo)號(hào)標(biāo)號(hào) 宏名宏名 $參數(shù)參數(shù)1,$參數(shù)參數(shù)2,語句段語句段MEXIT語句段語句段MENDMACRO、M

24、END和和MEXIT都是宏定義指令。都是宏定義指令。4.1.1 通用偽指令通用偽指令u偽指令偽指令MACRO定義一個(gè)宏語句段的開始定義一個(gè)宏語句段的開始;偽指令;偽指令MEND定義宏語句段的結(jié)束定義宏語句段的結(jié)束;偽指令;偽指令MEXIT可以實(shí)可以實(shí)現(xiàn)從宏程序段的跳出現(xiàn)從宏程序段的跳出。宏指令可以使用一個(gè)或多個(gè)參。宏指令可以使用一個(gè)或多個(gè)參數(shù),當(dāng)宏指令被展開時(shí),這些參數(shù)被相應(yīng)的值替換。數(shù),當(dāng)宏指令被展開時(shí),這些參數(shù)被相應(yīng)的值替換。MACRO、MEND偽指令可以嵌套使用。偽指令可以嵌套使用。u宏宏是一段功能完整的程序,能夠?qū)崿F(xiàn)一個(gè)特定的功能,是一段功能完整的程序,能夠?qū)崿F(xiàn)一個(gè)特定的功能,在使用中

25、可以把它視為一個(gè)子程序。在其他程序中,在使用中可以把它視為一個(gè)子程序。在其他程序中,可以調(diào)用宏完成某個(gè)功能??梢哉{(diào)用宏完成某個(gè)功能。4.1.1 通用偽指令通用偽指令u調(diào)用宏是通過調(diào)用宏的名稱來實(shí)現(xiàn)的。宏指令的使用調(diào)用宏是通過調(diào)用宏的名稱來實(shí)現(xiàn)的。宏指令的使用方式和功能與子程序有些相似,子程序可以提供模塊方式和功能與子程序有些相似,子程序可以提供模塊化的程序設(shè)計(jì)、節(jié)省存儲(chǔ)空間并提高運(yùn)行速度。化的程序設(shè)計(jì)、節(jié)省存儲(chǔ)空間并提高運(yùn)行速度。u但在使用子程序結(jié)構(gòu)時(shí)需要保護(hù)現(xiàn)場(chǎng),從而增加了系但在使用子程序結(jié)構(gòu)時(shí)需要保護(hù)現(xiàn)場(chǎng),從而增加了系統(tǒng)的開銷,因此,統(tǒng)的開銷,因此,在代碼較短且需要傳遞的參數(shù)較多在代碼較短

26、且需要傳遞的參數(shù)較多時(shí),可以使用宏指令代替子程序。時(shí),可以使用宏指令代替子程序。調(diào)用宏的好處是不調(diào)用宏的好處是不占用傳送參數(shù)的寄存器,不用保護(hù)現(xiàn)場(chǎng)。占用傳送參數(shù)的寄存器,不用保護(hù)現(xiàn)場(chǎng)。4.1.1 通用偽指令通用偽指令指令示例:指令示例:MACRO;定義宏;定義宏$DATA1 MAX $N1,$N2;宏名稱是;宏名稱是MAX,主標(biāo)號(hào)是,主標(biāo)號(hào)是$DATA1,兩個(gè)參數(shù),兩個(gè)參數(shù)語句段語句段;語句段;語句段$DATA1.MAY1;非主標(biāo)號(hào),由主標(biāo)號(hào)構(gòu)成;非主標(biāo)號(hào),由主標(biāo)號(hào)構(gòu)成語句段語句段;語句段;語句段$DATA1.MAY2;非主標(biāo)號(hào),由主標(biāo)號(hào)構(gòu)成;非主標(biāo)號(hào),由主標(biāo)號(hào)構(gòu)成MEND;宏結(jié)束;宏結(jié)束4.

27、1.1 通用偽指令通用偽指令(2)IF、ELSE、ENDIF語法格式:語法格式:IF 邏輯表達(dá)式邏輯表達(dá)式語句段語句段1ELSE語句段語句段2ENDIFlIF、ELSE、ENDIF偽指令是偽指令是條件分支偽指令條件分支偽指令,能根據(jù)條件的,能根據(jù)條件的成立與否決定是否執(zhí)行某個(gè)語句。偽指令成立與否決定是否執(zhí)行某個(gè)語句。偽指令I(lǐng)F可以對(duì)條件進(jìn)行判可以對(duì)條件進(jìn)行判斷;偽指令斷;偽指令ELSE產(chǎn)生分支;偽指令產(chǎn)生分支;偽指令ENDIF定義分支結(jié)束。定義分支結(jié)束。l當(dāng)當(dāng)IF后面的邏輯表達(dá)式為真,則執(zhí)行語句段后面的邏輯表達(dá)式為真,則執(zhí)行語句段1,否則執(zhí)行語句,否則執(zhí)行語句段段2。其中,。其中,ELSE及語

28、句段及語句段2可以沒有,此時(shí),當(dāng)可以沒有,此時(shí),當(dāng)IF后面的邏后面的邏輯表達(dá)式為真,則執(zhí)行指令序列輯表達(dá)式為真,則執(zhí)行指令序列1,否則繼續(xù)執(zhí)行后面的指令。,否則繼續(xù)執(zhí)行后面的指令。IF、ELSE、ENDIF偽指令可以嵌套使用。偽指令可以嵌套使用。4.1.1 通用偽指令通用偽指令指令示例:指令示例: R0=0 x10 ;判斷;判斷R0中的內(nèi)容是否是中的內(nèi)容是否是0 x10ADD R0,R1,R2 ;如果;如果R0= 0 x10,則執(zhí)行,則執(zhí)行R0= R1+ R2ADD R0,R1,R3 ;如果;如果R0 0 x10,則執(zhí)行,則執(zhí)行R0= R1+ R3ENDIF4.1.1 通用偽指令通用偽指令(3

29、)WHILE、WEND語法格式:語法格式:WHILE邏輯表達(dá)式邏輯表達(dá)式語句段語句段WENDuWHILE、WEND偽指令是條件循環(huán)偽指令,能根據(jù)偽指令是條件循環(huán)偽指令,能根據(jù)條件的成立與否決定是否循環(huán)執(zhí)行某個(gè)語句段。偽指條件的成立與否決定是否循環(huán)執(zhí)行某個(gè)語句段。偽指令令WHILE對(duì)條件進(jìn)行判斷,滿足條件循環(huán),不滿足對(duì)條件進(jìn)行判斷,滿足條件循環(huán),不滿足條件結(jié)束循環(huán);偽指令條件結(jié)束循環(huán);偽指令WEND定義循環(huán)體結(jié)束。定義循環(huán)體結(jié)束。u當(dāng)當(dāng)WHILE后面的邏輯表達(dá)式為真,則執(zhí)行語句段,后面的邏輯表達(dá)式為真,則執(zhí)行語句段,該語句段執(zhí)行完畢后,再判斷邏輯表達(dá)式的值,若為該語句段執(zhí)行完畢后,再判斷邏輯表達(dá)

30、式的值,若為真則繼續(xù)執(zhí)行,一直到邏輯表達(dá)式的值為假。真則繼續(xù)執(zhí)行,一直到邏輯表達(dá)式的值為假。4.1.1 通用偽指令通用偽指令指令示例:指令示例:GBLA Cou1;聲明一個(gè)全局的數(shù)學(xué)變量,變量名為;聲明一個(gè)全局的數(shù)學(xué)變量,變量名為CounterCou1 SETA 1;為;為Cou1賦值賦值1WHILE Cou1 10;判斷;判斷WHILECounter ”、“=”、“= ”、“/=”、“ ” 運(yùn)算符。運(yùn)算符。以以A和和B表示兩個(gè)邏輯表達(dá)式,以上的運(yùn)算符代表表示兩個(gè)邏輯表達(dá)式,以上的運(yùn)算符代表的運(yùn)算如下:的運(yùn)算如下:A = B表示表示A等于等于B。A B表示表示A大于大于B。A = B表示表示A

31、大于等于大于等于B。A = B表示表示A小于等于小于等于B。A /= B表示表示A不等于不等于B。X B表示表示A不等于不等于B。4.2.2 匯編語言中表達(dá)式和運(yùn)算符匯編語言中表達(dá)式和運(yùn)算符指令示例指令示例:MOV R5,#0 xFF00:MOD:0 xF:ROL:2;R5寄存器里的內(nèi)容為寄存器里的內(nèi)容為0 x00IF R5:LAND:R6=R7MOV R0,#0 x00ELSEMOV R0,#0 xFF ;如果;如果R5R6、=、=、/=、)邏輯運(yùn)算(邏輯運(yùn)算(LAND、LOR、LEOR)表表4-3 運(yùn)算符優(yōu)先級(jí)運(yùn)算符優(yōu)先級(jí)4.3 匯編程序應(yīng)用匯編程序應(yīng)用4.3.1 匯編程序基本結(jié)構(gòu)匯編程序

32、基本結(jié)構(gòu)下面是一個(gè)匯編語言源程序的基本結(jié)構(gòu):下面是一個(gè)匯編語言源程序的基本結(jié)構(gòu): AREA example,CODE,READONLY ;定義代碼塊為;定義代碼塊為exampleENTRY ;程序入口;程序入口StartMOV R0, #40 ;R0=40MOV R1,#16;R1=16 ADD R2,R0,R1;R2= R0 +R1MOV R0,#0 x18;傳送到軟件中斷的參數(shù);傳送到軟件中斷的參數(shù)LDR R1,=0 x20026;傳送到軟件中斷的參數(shù);傳送到軟件中斷的參數(shù)SWI 0 x123456;通過軟件中斷指令返回;通過軟件中斷指令返回END ;文件結(jié)束;文件結(jié)束4.3.1 匯編程序

33、基本結(jié)構(gòu)匯編程序基本結(jié)構(gòu)uAREA 偽指令定義一個(gè)段,并說明所定義段的相關(guān)偽指令定義一個(gè)段,并說明所定義段的相關(guān)屬性,本例定義一個(gè)名為屬性,本例定義一個(gè)名為 example 的代碼段,屬性的代碼段,屬性為只讀。為只讀。u ENTRY 偽指令標(biāo)識(shí)程序的入口點(diǎn),接下來為語句偽指令標(biāo)識(shí)程序的入口點(diǎn),接下來為語句段。執(zhí)行主代碼后,通過返回控制終止應(yīng)用程序并段。執(zhí)行主代碼后,通過返回控制終止應(yīng)用程序并返回到返回到DEBUG,通過使用軟件中斷指令實(shí)現(xiàn)了返回。,通過使用軟件中斷指令實(shí)現(xiàn)了返回。u在程序的末尾為在程序的末尾為 END 偽指令,該偽指令通知編譯器偽指令,該偽指令通知編譯器停止對(duì)源文件的處理,每一

34、個(gè)匯編程序段都必須有停止對(duì)源文件的處理,每一個(gè)匯編程序段都必須有一條一條END偽指令,指示代碼段的結(jié)束。偽指令,指示代碼段的結(jié)束。4.3.2 子程序調(diào)用子程序調(diào)用2. 在在ARM匯編語言程序中,子程序的調(diào)用一般是通過匯編語言程序中,子程序的調(diào)用一般是通過BL指令來實(shí)現(xiàn)的。指令來實(shí)現(xiàn)的。3. 指令格式:指令格式:BL子程序名子程序名 該指令在執(zhí)行時(shí)完成如下操作:將子程序的返回地該指令在執(zhí)行時(shí)完成如下操作:將子程序的返回地址存放在連接寄存器址存放在連接寄存器LR中,同時(shí)將程序計(jì)數(shù)器中,同時(shí)將程序計(jì)數(shù)器PC指指向子程序的入口點(diǎn),當(dāng)子程序執(zhí)行完畢需要返回調(diào)向子程序的入口點(diǎn),當(dāng)子程序執(zhí)行完畢需要返回調(diào)用

35、處時(shí),只需要將存放在用處時(shí),只需要將存放在LR中的返回地址重新拷貝中的返回地址重新拷貝給程序計(jì)數(shù)器給程序計(jì)數(shù)器PC(即:使用指令(即:使用指令MOV PC,LR)。)。4.3.2 子程序調(diào)用子程序調(diào)用 習(xí)慣上用寄存器習(xí)慣上用寄存器R0R3來存放送到子程序的參來存放送到子程序的參數(shù),然后從子程序返回時(shí)存放返回的結(jié)果給調(diào)用者。數(shù),然后從子程序返回時(shí)存放返回的結(jié)果給調(diào)用者。 下面給出的子程序,減下面給出的子程序,減4個(gè)參數(shù)的值,用個(gè)參數(shù)的值,用R0返回返回結(jié)果(即實(shí)現(xiàn)結(jié)果(即實(shí)現(xiàn)R0=R0-R1-R2-R3)。)。4.3.2 子程序調(diào)用子程序調(diào)用AREA Init,CODE,READONLY ;定義

36、一個(gè)代碼段;定義一個(gè)代碼段ENTRY ;定義一個(gè)程序入口;定義一個(gè)程序入口LOOP1 MOV R0,#412;給參數(shù);給參數(shù)R0賦值賦值680MOV R1,# 106 ;給參數(shù);給參數(shù)R1賦值賦值25MOV R2,# 64;給參數(shù);給參數(shù)R2賦值賦值101MOV R3,# 195 ;給參數(shù);給參數(shù)R3賦值賦值91BL SUB1 ;調(diào)用子程序;調(diào)用子程序SUB1,同時(shí)將子程序的返回,同時(shí)將子程序的返回;地址存放在連接寄存器;地址存放在連接寄存器R14(LR)中。中。MOV R0,#0 x18 ;傳送到軟件中斷的參數(shù);傳送到軟件中斷的參數(shù)LDR R1,=0 x20026;傳送到軟件中斷的參數(shù);傳送

37、到軟件中斷的參數(shù)SWI 0 x123456;通過軟件中斷指令返回;通過軟件中斷指令返回SUB1SUB R0,R0,R1;子程序代碼;子程序代碼SUB R0,R0,R2SUB R0,R0,R3MOV PC,LR;從子程序返回;從子程序返回END4. 4 匯編語言與匯編語言與C/C+的混合編程的混合編程在應(yīng)用系統(tǒng)的程序設(shè)計(jì)中,若所有的編程任務(wù)均用匯編在應(yīng)用系統(tǒng)的程序設(shè)計(jì)中,若所有的編程任務(wù)均用匯編語言來完成,其工作量是可想而知的。事實(shí)上,語言來完成,其工作量是可想而知的。事實(shí)上,ARM體系結(jié)構(gòu)支持體系結(jié)構(gòu)支持C/C以及與匯編語言的混合編程以及與匯編語言的混合編程,在一個(gè)完整的程序設(shè)計(jì)的中,除了初始

38、化部分用匯編在一個(gè)完整的程序設(shè)計(jì)的中,除了初始化部分用匯編語言完成以外,其主要的編程任務(wù)一般都用語言完成以外,其主要的編程任務(wù)一般都用C/C+完完成。成。匯編語言與匯編語言與C/C+的混合編程通常有以下幾種的混合編程通常有以下幾種方式方式:l在在C/C代碼中嵌入?yún)R編指令。代碼中嵌入?yún)R編指令。l在匯編程序和在匯編程序和C/C的程序之間進(jìn)行變量的互訪。的程序之間進(jìn)行變量的互訪。l匯編程序、匯編程序、C/C程序間的相互調(diào)用。程序間的相互調(diào)用。4. 4 匯編語言與匯編語言與C/C+的混合編程的混合編程 在以上的幾種混合編程技術(shù)中,必須在以上的幾種混合編程技術(shù)中,必須遵守一定的調(diào)遵守一定的調(diào)用規(guī)則用規(guī)則

39、:這里所指的是:這里所指的是ATPCS規(guī)則,規(guī)則,PCS即即Procedure Call Standard(過程調(diào)用規(guī)范),(過程調(diào)用規(guī)范),ATPCS即即ARM-THUMB procedure call standard。PCS規(guī)定規(guī)定了應(yīng)用程序的函數(shù)可以如何分開地寫,分開地編譯,了應(yīng)用程序的函數(shù)可以如何分開地寫,分開地編譯,最后將它們連接在一起,所以它實(shí)際上定義了一套有最后將它們連接在一起,所以它實(shí)際上定義了一套有關(guān)過程(函數(shù))調(diào)用者與被調(diào)用者之間的協(xié)議關(guān)過程(函數(shù))調(diào)用者與被調(diào)用者之間的協(xié)議。4. 4 匯編語言與匯編語言與C/C+的混合編程的混合編程uPCS強(qiáng)制實(shí)現(xiàn)如下強(qiáng)制實(shí)現(xiàn)如下約定約

40、定:調(diào)用函數(shù)如何傳遞參數(shù)(即:調(diào)用函數(shù)如何傳遞參數(shù)(即壓棧方法,以何種方式存放參數(shù)),被調(diào)用函數(shù)如何壓棧方法,以何種方式存放參數(shù)),被調(diào)用函數(shù)如何獲取參數(shù),以何種方式傳遞函數(shù)返回值。獲取參數(shù),以何種方式傳遞函數(shù)返回值。uPCS的制訂是一系列指標(biāo)的的制訂是一系列指標(biāo)的“tradeoff(折衷)(折衷)”(因?yàn)楹艽蟪潭壬仙婕跋到y(tǒng)的一些性能),如:會(huì)涉(因?yàn)楹艽蟪潭壬仙婕跋到y(tǒng)的一些性能),如:會(huì)涉及生成代碼的大小,調(diào)試功能的支持,函數(shù)調(diào)用上下及生成代碼的大小,調(diào)試功能的支持,函數(shù)調(diào)用上下文處理速度以及內(nèi)存消耗等。文處理速度以及內(nèi)存消耗等。u當(dāng)然,通過編譯器的支持可以讓生成的代碼有不同的當(dāng)然,通過編譯

41、器的支持可以讓生成的代碼有不同的特性,如:特性,如:gcc編譯選項(xiàng)可以支持或不支持編譯選項(xiàng)可以支持或不支持frame pointer來支持深入調(diào)試功能或提高程序運(yùn)行性能。來支持深入調(diào)試功能或提高程序運(yùn)行性能。4. 4 匯編語言與匯編語言與C/C+的混合編程的混合編程u基本基本ATPCS規(guī)定了在子程序調(diào)用時(shí)的一些基本規(guī)則,規(guī)定了在子程序調(diào)用時(shí)的一些基本規(guī)則,包括以下三個(gè)方面的內(nèi)容:各寄存器的使用規(guī)則及其包括以下三個(gè)方面的內(nèi)容:各寄存器的使用規(guī)則及其相應(yīng)的名字;數(shù)據(jù)棧的使用規(guī)則;參數(shù)傳遞的規(guī)則。相應(yīng)的名字;數(shù)據(jù)棧的使用規(guī)則;參數(shù)傳遞的規(guī)則。u相對(duì)于其他類型的相對(duì)于其他類型的ATPCS,滿足基本,滿

42、足基本ATPCS的程序的程序的執(zhí)行速度更快,所占用的內(nèi)存更少。但是它不能提的執(zhí)行速度更快,所占用的內(nèi)存更少。但是它不能提供以下的支持供以下的支持ARM程序和程序和THUMB程序相互調(diào)用;數(shù)程序相互調(diào)用;數(shù)據(jù)以及代碼的位置無關(guān);子程序的可重入性;數(shù)據(jù)棧據(jù)以及代碼的位置無關(guān);子程序的可重入性;數(shù)據(jù)棧檢查等。檢查等。4. 4 匯編語言與匯編語言與C/C+的混合編程的混合編程1.各寄存器的使用規(guī)則各寄存器的使用規(guī)則(1)子程序通過寄存器)子程序通過寄存器R0R3來傳遞參數(shù)。來傳遞參數(shù)。 這時(shí)寄存這時(shí)寄存器可以記作:器可以記作: A0A3 ,被調(diào)用的子程序在返回前無,被調(diào)用的子程序在返回前無需恢復(fù)寄存器

43、需恢復(fù)寄存器R0R3的內(nèi)容。的內(nèi)容。(2)在子程序中,使用)在子程序中,使用R4R11來保存局部變量來保存局部變量,這時(shí)寄這時(shí)寄存器存器R4R11可以記作:可以記作:V1V8。如果在子程序中使。如果在子程序中使用到用到V1V8的某些寄存器,子程序進(jìn)入時(shí)必須保存這的某些寄存器,子程序進(jìn)入時(shí)必須保存這些寄存器的值,在返回前必須恢復(fù)這些寄存器的值,些寄存器的值,在返回前必須恢復(fù)這些寄存器的值,對(duì)于子程序中沒有用到的寄存器則不必執(zhí)行這些操作。對(duì)于子程序中沒有用到的寄存器則不必執(zhí)行這些操作。在在THUMB程序中,通常只能使用寄存器程序中,通常只能使用寄存器R4R7來保來保存局部變量。存局部變量。(3)寄

44、存器)寄存器R12用作子程序間用作子程序間scratch寄存器,記作寄存器,記作ip;在子程序的連接代碼段中經(jīng)常會(huì)有這種使用規(guī)則。在子程序的連接代碼段中經(jīng)常會(huì)有這種使用規(guī)則。4. 4 匯編語言與匯編語言與C/C+的混合編程的混合編程(4)寄存器)寄存器R13用作數(shù)據(jù)棧指針,記做用作數(shù)據(jù)棧指針,記做SP;在子程序;在子程序中寄存器中寄存器R13不能用做其他用途。不能用做其他用途。 寄存器寄存器SP在進(jìn)入子在進(jìn)入子程序時(shí)的值和退出子程序時(shí)的值必須相等。程序時(shí)的值和退出子程序時(shí)的值必須相等。(5)寄存器)寄存器R14用作連接寄存器,記作用作連接寄存器,記作lr ;它用于保存;它用于保存子程序的返回地

45、址,如果在子程序中保存了返回地址,子程序的返回地址,如果在子程序中保存了返回地址,則則R14可用作其它的用途??捎米髌渌挠猛尽#?)寄存器)寄存器R15是程序計(jì)數(shù)器,記作是程序計(jì)數(shù)器,記作PC ;它不能用作;它不能用作其他用途。其他用途。(7)ATPCS中的各寄存器在中的各寄存器在ARM編譯器和匯編器中都編譯器和匯編器中都是預(yù)定義的。是預(yù)定義的。4. 4 匯編語言與匯編語言與C/C+的混合編程的混合編程2.數(shù)據(jù)棧的使用規(guī)則數(shù)據(jù)棧的使用規(guī)則 ATPCS規(guī)定數(shù)據(jù)棧為滿遞減類型。并對(duì)數(shù)據(jù)棧的規(guī)定數(shù)據(jù)棧為滿遞減類型。并對(duì)數(shù)據(jù)棧的操作是操作是8字節(jié)對(duì)齊的,下面是一個(gè)數(shù)據(jù)棧的示例及相字節(jié)對(duì)齊的,下面是一

46、個(gè)數(shù)據(jù)棧的示例及相關(guān)的名詞。關(guān)的名詞。(1)數(shù)據(jù)棧棧指針()數(shù)據(jù)棧棧指針(stack pointer ),其指向最后一),其指向最后一個(gè)寫入棧的數(shù)據(jù)的內(nèi)存地址。個(gè)寫入棧的數(shù)據(jù)的內(nèi)存地址。(2)數(shù)據(jù)棧的基地址()數(shù)據(jù)棧的基地址(stack base),是指數(shù)據(jù)棧的最),是指數(shù)據(jù)棧的最高地址。由于高地址。由于ATPCS中的數(shù)據(jù)棧是中的數(shù)據(jù)棧是FD類型的,實(shí)際類型的,實(shí)際上數(shù)據(jù)棧中最早入棧數(shù)據(jù)占據(jù)的內(nèi)存單元是基地址的上數(shù)據(jù)棧中最早入棧數(shù)據(jù)占據(jù)的內(nèi)存單元是基地址的下一個(gè)內(nèi)存單元。下一個(gè)內(nèi)存單元。4. 4 匯編語言與匯編語言與C/C+的混合編程的混合編程(3)數(shù)據(jù)棧界限()數(shù)據(jù)棧界限(stack lim

47、it ),是指數(shù)據(jù)棧中可以使),是指數(shù)據(jù)棧中可以使用的最低的內(nèi)存單元地址。用的最低的內(nèi)存單元地址。 (4)已占用的數(shù)據(jù)棧()已占用的數(shù)據(jù)棧(used stack),是指數(shù)據(jù)棧的基),是指數(shù)據(jù)棧的基地址和數(shù)據(jù)棧棧指針之間的區(qū)域,其中包括數(shù)據(jù)棧棧地址和數(shù)據(jù)棧棧指針之間的區(qū)域,其中包括數(shù)據(jù)棧棧指針對(duì)應(yīng)的內(nèi)存單元。指針對(duì)應(yīng)的內(nèi)存單元。(5)數(shù)據(jù)棧中的數(shù)據(jù)幀)數(shù)據(jù)棧中的數(shù)據(jù)幀(stack frames) ,是指在數(shù)據(jù)棧,是指在數(shù)據(jù)棧中中,為子程序分配的用來保存寄存器和局部變量的區(qū)為子程序分配的用來保存寄存器和局部變量的區(qū)域。域。異常中斷的處理程序可以使用被中斷程序的數(shù)據(jù)棧,異常中斷的處理程序可以使用被中

48、斷程序的數(shù)據(jù)棧,這時(shí)用戶要保證中斷的程序數(shù)據(jù)棧足夠大。這時(shí)用戶要保證中斷的程序數(shù)據(jù)棧足夠大。 4. 4 匯編語言與匯編語言與C/C+的混合編程的混合編程3.參數(shù)的傳遞規(guī)則參數(shù)的傳遞規(guī)則根據(jù)參數(shù)個(gè)數(shù)是否固定,可以將子程序分為參數(shù)個(gè)根據(jù)參數(shù)個(gè)數(shù)是否固定,可以將子程序分為參數(shù)個(gè)數(shù)固定的子程序和參數(shù)個(gè)數(shù)可變的子程序。數(shù)固定的子程序和參數(shù)個(gè)數(shù)可變的子程序。 (1)參數(shù)個(gè)數(shù)可變的子程序參數(shù)傳遞規(guī)則)參數(shù)個(gè)數(shù)可變的子程序參數(shù)傳遞規(guī)則對(duì)于參數(shù)個(gè)數(shù)可變的子程序,當(dāng)參數(shù)不超過對(duì)于參數(shù)個(gè)數(shù)可變的子程序,當(dāng)參數(shù)不超過4個(gè)時(shí),可個(gè)時(shí),可以使用寄存器以使用寄存器R0R3來進(jìn)行參數(shù)傳遞,當(dāng)參數(shù)超過來進(jìn)行參數(shù)傳遞,當(dāng)參數(shù)超過

49、4個(gè)時(shí),還可以使用數(shù)據(jù)棧來傳遞參數(shù)。在參數(shù)傳遞時(shí),個(gè)時(shí),還可以使用數(shù)據(jù)棧來傳遞參數(shù)。在參數(shù)傳遞時(shí),將所有參數(shù)看做是存放在連續(xù)的內(nèi)存單元中的字?jǐn)?shù)據(jù)。將所有參數(shù)看做是存放在連續(xù)的內(nèi)存單元中的字?jǐn)?shù)據(jù)。然后,依次將各名字?jǐn)?shù)據(jù)傳送到寄存器然后,依次將各名字?jǐn)?shù)據(jù)傳送到寄存器R0、R1、R2、R3;如果參數(shù)多于;如果參數(shù)多于4個(gè),將剩余的字?jǐn)?shù)據(jù)傳送到數(shù)據(jù)個(gè),將剩余的字?jǐn)?shù)據(jù)傳送到數(shù)據(jù)棧中,入棧的順序與參數(shù)順序相反,即最后一個(gè)字?jǐn)?shù)棧中,入棧的順序與參數(shù)順序相反,即最后一個(gè)字?jǐn)?shù)據(jù)先入棧。按照上面的規(guī)則,一個(gè)浮點(diǎn)數(shù)參數(shù)可以通據(jù)先入棧。按照上面的規(guī)則,一個(gè)浮點(diǎn)數(shù)參數(shù)可以通過寄存器傳遞,也可以通過數(shù)據(jù)棧傳遞,也可能一半

50、過寄存器傳遞,也可以通過數(shù)據(jù)棧傳遞,也可能一半通過寄存器傳遞,另一半通過數(shù)據(jù)棧傳遞。通過寄存器傳遞,另一半通過數(shù)據(jù)棧傳遞。4. 4 匯編語言與匯編語言與C/C+的混合編程的混合編程(2)參數(shù)個(gè)數(shù)固定的子程序參數(shù)傳遞規(guī)則)參數(shù)個(gè)數(shù)固定的子程序參數(shù)傳遞規(guī)則對(duì)于參數(shù)個(gè)數(shù)固定的子程序,參數(shù)傳遞與參數(shù)個(gè)數(shù)對(duì)于參數(shù)個(gè)數(shù)固定的子程序,參數(shù)傳遞與參數(shù)個(gè)數(shù)可變的子程序參數(shù)傳遞規(guī)則不同,如果系統(tǒng)包含浮點(diǎn)可變的子程序參數(shù)傳遞規(guī)則不同,如果系統(tǒng)包含浮點(diǎn)運(yùn)算的硬件部件,浮點(diǎn)參數(shù)將按照下面的規(guī)則傳遞:運(yùn)算的硬件部件,浮點(diǎn)參數(shù)將按照下面的規(guī)則傳遞:各個(gè)浮點(diǎn)參數(shù)按順序處理;為每個(gè)浮點(diǎn)參數(shù)分配各個(gè)浮點(diǎn)參數(shù)按順序處理;為每個(gè)浮點(diǎn)

51、參數(shù)分配FP寄存器;分配的方法是滿足該浮點(diǎn)參數(shù)需要的且編號(hào)寄存器;分配的方法是滿足該浮點(diǎn)參數(shù)需要的且編號(hào)最小的一組連續(xù)的最小的一組連續(xù)的FP寄存器。第一個(gè)整數(shù)參數(shù)通過寄存器。第一個(gè)整數(shù)參數(shù)通過寄存器寄存器R0R3來傳遞,其他參數(shù)通過數(shù)據(jù)棧傳遞。來傳遞,其他參數(shù)通過數(shù)據(jù)棧傳遞。4. 4 匯編語言與匯編語言與C/C+的混合編程的混合編程4.子程序結(jié)果返回規(guī)則子程序結(jié)果返回規(guī)則 (1)結(jié)果為一個(gè))結(jié)果為一個(gè)32位的整數(shù)時(shí)位的整數(shù)時(shí),可以通過寄存器可以通過寄存器R0返回。返回。 (2)結(jié)果為一個(gè))結(jié)果為一個(gè)64位整數(shù)時(shí)位整數(shù)時(shí),可以通過可以通過R0和和R1返回,返回,依此類推。依此類推。 (3)對(duì)于位

52、數(shù)更多的結(jié)果)對(duì)于位數(shù)更多的結(jié)果,需要通過調(diào)用內(nèi)存來傳遞。需要通過調(diào)用內(nèi)存來傳遞。4. 4 匯編語言與匯編語言與C/C+的混合編程的混合編程 如果按照上述的方法,就過于繁瑣。在實(shí)際的編程應(yīng)如果按照上述的方法,就過于繁瑣。在實(shí)際的編程應(yīng)用中,使用較多的方式是:用中,使用較多的方式是: 程序的初始化部分用匯編語言完成,然后用程序的初始化部分用匯編語言完成,然后用C/C完成主要的編程任務(wù),程序在執(zhí)行時(shí)首先完成初始化完成主要的編程任務(wù),程序在執(zhí)行時(shí)首先完成初始化過程,然后跳轉(zhuǎn)到過程,然后跳轉(zhuǎn)到C/C程序代碼中,匯編程序和程序代碼中,匯編程序和C/C程序之間一般沒有參數(shù)的傳遞,也沒有頻繁程序之間一般沒有

53、參數(shù)的傳遞,也沒有頻繁的相互調(diào)用,因此,整個(gè)程序的結(jié)構(gòu)顯得相對(duì)簡(jiǎn)單,的相互調(diào)用,因此,整個(gè)程序的結(jié)構(gòu)顯得相對(duì)簡(jiǎn)單,容易理解。容易理解。4.4.1 在在C/C+程序程序中內(nèi)嵌匯編指令的語法格式中內(nèi)嵌匯編指令的語法格式在在ARM C語言程序中使用語言程序中使用關(guān)鍵字關(guān)鍵字_asm來標(biāo)識(shí)一段匯編指令程序,來標(biāo)識(shí)一段匯編指令程序,其用法如下:其用法如下:_asm instruction ; instruction 匯編語言程序段以及注釋匯編語言程序段以及注釋instruction其中,如果一行中有多個(gè)匯編指令,指令之間使用分號(hào)其中,如果一行中有多個(gè)匯編指令,指令之間使用分號(hào)“;”隔隔開;如果一條指令占

54、多行,使用續(xù)行符號(hào)開;如果一條指令占多行,使用續(xù)行符號(hào)”表示接續(xù);在匯表示接續(xù);在匯編指令段中可以使用編指令段中可以使用C語言的注釋語句。語言的注釋語句。在在ARM C/C+程序中還可以使用關(guān)鍵詞程序中還可以使用關(guān)鍵詞asm來內(nèi)嵌一段匯編程序,來內(nèi)嵌一段匯編程序,其格式如下:其格式如下:asm(“instruction ; instruction”);其中,其中,asm后面括號(hào)中必須是一條匯編語句,且其不能包含注釋后面括號(hào)中必須是一條匯編語句,且其不能包含注釋語句。語句。4.4.2 C/C+與匯編語言的混合編程應(yīng)用與匯編語言的混合編程應(yīng)用這里主要討論這里主要討論C/C+和匯編的混合編程,包括相

55、互之間和匯編的混合編程,包括相互之間的函數(shù)調(diào)用。下面分五種情況來進(jìn)行討論。的函數(shù)調(diào)用。下面分五種情況來進(jìn)行討論。1在在C語言中內(nèi)嵌匯編語言中內(nèi)嵌匯編在在C中內(nèi)嵌的匯編指令包含大部分的中內(nèi)嵌的匯編指令包含大部分的ARM和和Thumb指令,不過其使用與匯編文件中的指令有些不指令,不過其使用與匯編文件中的指令有些不同,存在一些限制,主要有下面幾個(gè)方面:同,存在一些限制,主要有下面幾個(gè)方面:(1)不能直接向)不能直接向PC寄存器賦值,程序跳轉(zhuǎn)要使用寄存器賦值,程序跳轉(zhuǎn)要使用B或或者者BL指令。指令。 (2)在使用物理寄存器時(shí),不要使用過于復(fù)雜的)在使用物理寄存器時(shí),不要使用過于復(fù)雜的C表達(dá)表達(dá)式,避免

56、物理寄存器沖突。式,避免物理寄存器沖突。(3)R12和和R13可能被編譯器用來存放中間編譯結(jié)果,可能被編譯器用來存放中間編譯結(jié)果,計(jì)算表達(dá)式值時(shí)可能將計(jì)算表達(dá)式值時(shí)可能將R0R3、R12及及R14用于子程用于子程序調(diào)用,因此要避免直接使用這些物理寄存器。序調(diào)用,因此要避免直接使用這些物理寄存器。4.4.2 C/C+與匯編語言的混合編程應(yīng)用與匯編語言的混合編程應(yīng)用(4)一般不要直接指定物理寄存器,而讓編譯器進(jìn)行分配。)一般不要直接指定物理寄存器,而讓編譯器進(jìn)行分配。下面通過一個(gè)例子來說明如何在下面通過一個(gè)例子來說明如何在C中內(nèi)嵌匯編語言:中內(nèi)嵌匯編語言:#include void my_strc

57、py(const char *src, char *dest) /聲明一個(gè)函數(shù)聲明一個(gè)函數(shù)char ch; /聲明一個(gè)字符型變量聲明一個(gè)字符型變量LOOP ;循環(huán)入口;循環(huán)入口LDRB CH,SRC,#1 ;Thumb指令,指令,chsrc+1.將無符將無符;號(hào);號(hào)src地址的數(shù)地址的數(shù)+1送入送入chSTRB CH,dest,#1 ;Thumb指令,指令, dest+1 ch,;將無符號(hào);將無符號(hào)CH數(shù)據(jù)送入數(shù)據(jù)送入dest+1存儲(chǔ)存儲(chǔ)CMP CH, #0;比較;比較CH是否為零,否則循環(huán)。是否為零,否則循環(huán)。;總共循環(huán);總共循環(huán)256次次BNE LOOP;B 指令跳轉(zhuǎn),指令跳轉(zhuǎn),NE為為Z

58、位清零不相等位清零不相等4.4.2 C/C+與匯編語言的混合編程應(yīng)用與匯編語言的混合編程應(yīng)用char *a = forget it and move on!;/聲明字符型指針聲明字符型指針變量變量char b64;/字符型數(shù)組字符型數(shù)組printf(original: %s, a);/屏幕輸出,屏幕輸出,a的數(shù)值的數(shù)值printf(copyed: %s, b);/屏幕輸出,屏幕輸出,b的數(shù)值的數(shù)值return 0;在這里在這里C和匯編之間的值傳遞是用和匯編之間的值傳遞是用C的指針來實(shí)現(xiàn)的,的指針來實(shí)現(xiàn)的,因?yàn)橹羔槍?duì)應(yīng)的是地址,所以匯編中也可以訪問。因?yàn)橹羔槍?duì)應(yīng)的是地址,所以匯編中也可以訪問。4

59、.4.2 C/C+與匯編語言的混合編程應(yīng)用與匯編語言的混合編程應(yīng)用2在匯編中使用在匯編中使用C程序全局變量程序全局變量?jī)?nèi)嵌匯編不用單獨(dú)編輯匯編語言文件,比較簡(jiǎn)潔,內(nèi)嵌匯編不用單獨(dú)編輯匯編語言文件,比較簡(jiǎn)潔,但是有諸多限制,當(dāng)匯編的代碼較多時(shí)一般放在單獨(dú)但是有諸多限制,當(dāng)匯編的代碼較多時(shí)一般放在單獨(dú)的匯編文件中。這時(shí)就需要在匯編和的匯編文件中。這時(shí)就需要在匯編和C之間進(jìn)行一些之間進(jìn)行一些數(shù)據(jù)的傳遞,最簡(jiǎn)便的辦法就是使用全局變量。具體數(shù)據(jù)的傳遞,最簡(jiǎn)便的辦法就是使用全局變量。具體的匯編程序中訪問方法如下:的匯編程序中訪問方法如下:(2)使用)使用LDR指令讀取該全局變量的內(nèi)存地址,通常指令讀取該全

60、局變量的內(nèi)存地址,通常該全局變量的內(nèi)存地址值存放在程序的數(shù)據(jù)緩沖池中該全局變量的內(nèi)存地址值存放在程序的數(shù)據(jù)緩沖池中(Literal pool)。)。(3)根據(jù)該數(shù)據(jù)的類型,使用相應(yīng)的)根據(jù)該數(shù)據(jù)的類型,使用相應(yīng)的LDR/STR指令讀指令讀取取/修改該全局變量的值。修改該全局變量的值。4.4.2 C/C+與匯編語言的混合編程應(yīng)用與匯編語言的混合編程應(yīng)用下面通過一個(gè)例子來說明如何在匯編程序中訪問下面通過一個(gè)例子來說明如何在匯編程序中訪問C程序全局變程序全局變量。量。AREA asmfile,CODE,READONLY ;建立一個(gè)匯編程序段;建立一個(gè)匯編程序段EXPORT asmDouble ;聲明可以被調(diào)

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(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)論