在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計應(yīng)用 > ARM匯編語言中的偽操作(一)

            ARM匯編語言中的偽操作(一)

            作者: 時間:2016-11-11 來源:網(wǎng)絡(luò) 收藏
            偽操作(derective)是ARM匯編語言程序里的一些特殊的指令助記符,其作用主要是為完成匯編程序做各種準(zhǔn)備工作,在源程序運行匯編程序處理,而不是在計算機運行期間有機器執(zhí)行.也就是說,這些偽操作只是匯編過程中起作用,一旦匯編結(jié)束,偽操作的使命也就隨之消失.

            符號定義( Symbol Definition )偽操作
            符號定義偽操作用于定義 ARM 匯編程序中的變量、對變量賦值以及定義寄存器的別名。
            包括以下偽操作:
            — 用于聲明全局變量 GBLA 、 GBLL 和 GBLS 。
            — 用于聲明局部變量 LCLA 、 LCLL 和 LCLS 。
            — 用于對變量賦值 SETA 、 SETL 、 SETS 。
            — 為通用寄存器列表定義名稱 RLIST 。

            本文引用地址:http://www.biyoush.com/article/201611/316615.htm

            —為協(xié)處理器的寄存器定義名稱 CN
            — 為協(xié)處理器定義名稱 CP
            — 為VFP的寄存器定義名稱 DN、SN
            — 為FPA的浮點寄存器定義名稱 FN

            1、 GBLA、GBLL 和GBLS
            語法格式:
            GBLA ( GBLL 或 GBLS ) 全局變量名
            GBLA 、 GBLL 和 GBLS 偽操作用于聲明一個 ARM 程序中的全局變量,并將其初始化。其中:
            GBLA 偽操作用于聲明一個全局的算術(shù)變量,并初始化為 0 ;
            GBLL 偽操作用于聲明一個全局的邏輯變量,并初始化為 {FALSE};
            GBLS 偽操作用于聲明一個全局的字符串變量,并初始化為空串;
            全局變量名在其作用范圍內(nèi)必須唯一。 如果用這些偽操作重新聲明已經(jīng)聲明過的變量,則變量的值將 被初始化成后一次聲明語句中的值。
            使用示例:
            GBLA Test1 ;聲明一個全局的算術(shù)變量,變量名為 Test1
            Test1 SETA 0xaa ;將該變量賦值為 0xaa
            SPACE Test1 ;引用該變量

            GBLL Test2 ;聲明一個全局的邏輯變量,變量名為 Test2
            Test2 SETL {TRUE} ;將該變量賦值為真
            GBLS Test3 ;聲明一個全局的字符串變量,變量名為 Test3
            Test3 SETS “ Testing ” ;將該變量賦值為 “ Testing ”

            2、 LCLA、LCLL 和LCLS
            語法格式:
            LCLA ( LCLL 或 LCLS ) 局部變量名
            LCLA 、 LCLL 和 LCLS 偽操作用于聲明一個 ARM 程序中的局部變量,并將其初始化。其中:
            LCLA 偽操作用于聲明一個局部的數(shù)字變量,并初始化為 0 ;
            LCLL 偽操作用于聲明一個局部的邏輯變量,并初始化為 {FALSE};
            LCLS 偽操作用于聲明一個局部的字符串變量,并初始化為空串;
            使用示例:
            MACRO ;聲明一個宏

            $label message $a ;宏的原型

            LCLS err ;聲明一個局部串變量err

            err SETS “error no: “ ;向該變量賦值

            $label ;代碼

            INFO 0, “err”:CC: :STR: $a ;使用該串變量

            MEND ;宏定義結(jié)束

            3、 SETA、SETL 和SETS
            語法格式:
            變量名 SETA ( SETL 或 SETS ) 表達(dá)式
            偽操作 SETA 、 SETL 、 SETS 用于給一個ARM程序中的變量賦值。
            SETA 偽操作用于給一個算術(shù)變量賦值;
            SETL 偽操作用于給一個邏輯變量賦值;
            SETS 偽操作用于給一個字符串變量賦值;
            其中,變量名為已經(jīng)定義過的全局變量或局部變量,表達(dá)式為將要賦給變量的值。 在向變量賦值前,必須先聲明該變量。

            4 、 RLIST
            語法格式:
            名稱 RLIST { 寄存器列表 }
            RLIST 偽操作用于對一個通用寄存器列表定義名稱,定義的名稱可在LDM/STM指令中使用。在 LDM/STM 指令中,寄存器列表中的寄存器的訪問次序總是先訪問編號較低的寄存器,再訪問編號較高的寄存器,而不管寄存器列表中各寄存器的排列順序。

            使用示例:
            RegList RLIST {R0-R5 , R8 , R10} ;將寄存器列表名稱定義為 RegList ,可在 ARM 指令 LDM/STM中通過該名稱訪問寄存器列表。


            5 、 CN

            語法格式:

            name CN expr

            其中:name 是該寄存器的名稱

            expr為協(xié)處理器的寄存器的編號,數(shù)值范圍為0~15。

            CN偽操作用于給一個協(xié)處理器的寄存器定義名稱。方便程序員記憶該寄存器的功能

            示例

            Power CN 6 ;將協(xié)處理器的寄存器6名稱定義為Power

            注:以下的偽操作類似(可參考CN)

            數(shù)據(jù)定義( Data Definition )偽操作
            數(shù)據(jù)定義偽操作包括以下偽操作:

            LTORG 聲明一個數(shù)據(jù)緩沖池的開始;

            MAP 定義一個結(jié)構(gòu)化的內(nèi)存表首地址;

            FIELD 定義結(jié)構(gòu)化的內(nèi)存表中的一個數(shù)據(jù)域;

            SPACE 分配一塊內(nèi)存單元,并用0初始化;

            DCB 分配一段字節(jié)的內(nèi)存單元,并用指定的數(shù)據(jù)初始化;

            DCD及DCDU 分配一段字的內(nèi)存單元,并用指定的數(shù)據(jù)初始化;

            DCDO 分配一段字的內(nèi)存單元,并將每個單元的內(nèi)容初始化成該單元相對于基態(tài)值的寄存器的偏移量;

            DCFD及DCFDU 分配一段雙字的內(nèi)存單元,并用雙精度的浮點數(shù)據(jù)初始化;

            DCFS及DCFSU 分配一段字的內(nèi)存單元, 并用單精度的浮點數(shù)據(jù)初始化;

            DCI 分配一段字節(jié)的內(nèi)存單元,用指定的數(shù)據(jù)初始化,指定內(nèi)存單元中存放的是代碼,而不是數(shù)據(jù);

            DCQ及DCQU 分配一段雙字的內(nèi)存單元,并用64位的整數(shù)數(shù)據(jù)初始化;

            DCW及DCWU 分配一段半字的內(nèi)存單元,并用指定的數(shù)據(jù)初始化;

            DATA 在代碼段中使用數(shù)據(jù)(現(xiàn)在已不再使用,僅用于保持向前兼容)。

            以下主要介紹幾種常用的:
            1、 DCB (“ = ”)
            語法格式:
            標(biāo)號 DCB 表達(dá)式
            用于分配一段字節(jié)內(nèi)存單元并用偽操作中指定的表達(dá)式初始化。其中,表達(dá)式可以為 -128~ 255 的數(shù)值或字符串。
            使用示例:
            Str DCB “ This is a test ! ” ;分配一片連續(xù)的字節(jié)存儲單元并初始化。

            2、DCD “ &”(或DCDU)
            語法格式:
            標(biāo)號 DCD (或 DCDU ) 表達(dá)式
            用于分配一段字內(nèi)存單元并用偽操作中指定的表達(dá)式初始化。其中,表達(dá)式可以為程序中的標(biāo)號或數(shù)字表達(dá)式。

            用DCD 分配的字存儲單元是字對齊的,而用 DCDU 分配的字存儲單元并不嚴(yán)格字對齊。
            使用示例:
            DataTest DCD 4,5,6 ;其值分別為4,5和6。
            data2 DCD memaddr+4 ;分配一個字單元,其值為程序中標(biāo)號memaddr加4個字節(jié)
            3、DCQ(或DCQU)
            語法格式:
            標(biāo)號 DCQ (或 DCQU ) 表達(dá)式
            用于分配一段以8個字節(jié)為單位的內(nèi)存并用偽操作中指定的表達(dá)式初始化。
            用 DCQ 分配的存儲單元是字對齊的,而用 DCQU 分配的存儲單元并不嚴(yán)格字對齊。
            使用示例:
            DataTest DCQ -255,2_101 ;2_101指的是二進(jìn)制的101

            4、 SPACE (“ % ”)
            語法格式:
            標(biāo)號 SPACE 表達(dá)式
            用于分配一塊內(nèi)存單元,并初始化為 0 。其中,表達(dá)式為要分配的字節(jié)數(shù)。
            使用示例:
            DataSpace SPACE 100 ;分配連續(xù) 100 字節(jié)的存儲單元并初始化為 0 。

            5、 MAP (“ ^ ”)
            語法格式:
            MAP 表達(dá)式 { ,基址寄存器 }
            用于定義一個結(jié)構(gòu)化的內(nèi)存表的首地址。
            表達(dá)式可以為程序中的標(biāo)號或數(shù)字表達(dá)式,基址寄存器為可選項,當(dāng)基址寄存器選項不存在時,表達(dá)式的值即為內(nèi)存表的首地址,當(dāng)該選項存在時,內(nèi)存表的首地址為表達(dá)式的值與基址寄存器的和。
            MAP 偽操作通常與 FIELD 偽操作配合使用來定義結(jié)構(gòu)化的內(nèi)存表。
            使用示例:
            MAP 0x100 , R9;定義結(jié)構(gòu)化內(nèi)存表首地址的值為 0x100 + R9 。

            6、 FILED (“ # ” )
            語法格式:
            標(biāo)號 FIELD 表達(dá)式
            用于定義一個結(jié)構(gòu)化內(nèi)存表中的數(shù)據(jù)域。
            表達(dá)式的值為當(dāng)前數(shù)據(jù)域在內(nèi)存表中所占的字節(jié)數(shù)。
            FIELD 偽操作常與 MAP 偽操作配合使用來定義結(jié)構(gòu)化的內(nèi)存表結(jié)構(gòu)。 MAP 偽操作定義內(nèi)存表的首地址, FIELD 偽操作定義內(nèi)存表中的各數(shù)據(jù)域的字節(jié)長度,并可以為每個數(shù)據(jù)域指定一個標(biāo)號供其他的指令引用。
            注意 MAP 和 FIELD 偽操作僅用于定義數(shù)據(jù)結(jié)構(gòu),并不實際分配存儲單元。
            示例1:
            下面的偽操作序列定義一個內(nèi)存表,其首地址為固定地址4096,該內(nèi)存表中包括5個數(shù)據(jù)域:consta長度為4個字節(jié);constb長度為4個字節(jié);x長度為8個字節(jié);y長度為8個字節(jié);string長度為256個字節(jié)。這種內(nèi)存表稱為基于絕對地址的內(nèi)存表。

            MAP 4096 ;內(nèi)存表的首地址為4096(0x1000)

            consta FIELD 4 ;consta長度為4個字節(jié),相對位置為0

            constb FIELD 4 ;constb長度為4個字節(jié),相對位置為5000

            x FIELD 8 ;x長度為4個字節(jié),相對位置為5004

            y FIELD 8 ;y長度為4個字節(jié),相對位置為5012

            string FIELD 256 ;string長度為256字節(jié),相對位置為5020

            ;在指令中可以這樣引用內(nèi)存表中的數(shù)據(jù)域:

            LDR R6,consta

            上面的指令僅僅可以訪問LDR指令前面(或后面)4KB地址范圍的數(shù)據(jù)域

            示例2:

            下面的偽操作序列定義一個內(nèi)存表,其首地址為0,該內(nèi)存表中包括5個數(shù)據(jù)域:consta長度為4個字節(jié);constb長度為4個字節(jié);x長度為8個字節(jié);y長度為8個字節(jié);string長度為256個字節(jié)。這種內(nèi)存表稱為基于相對地址的內(nèi)存表。

            MAP 4096 ;內(nèi)存表的首地址為0

            consta FIELD 4 ;consta長度為4個字節(jié),相對位置為0

            constb FIELD 4 ;constb長度為4個字節(jié),相對位置為4

            x FIELD 8 ;x長度為4個字節(jié),相對位置為8

            y FIELD 8 ;y長度為4個字節(jié),相對位置為16

            string FIELD 256 ;string長度為256字節(jié),相對位置為24

            ;可以通過下面的指令方便地訪問地址范圍超過4KB的數(shù)據(jù)

            MOV R9,#4096

            LDR R5,[R9,constb] ;將內(nèi)存表中數(shù)據(jù)域constb讀取到R5中

            在這里,內(nèi)存表中各數(shù)據(jù)域的實際內(nèi)存地址不是基于一個固定地址,而是基于LDR指令執(zhí)行時R9寄存器中的內(nèi)容。這樣通過上面方法定義的內(nèi)存表結(jié)構(gòu)可以在程序中有多個實例(通過在LDR指令中指定不同的基址寄存器值來實現(xiàn))。通常用R9作為靜態(tài)基址寄存器。

            7、LTORG

            用于聲明一個數(shù)據(jù)緩沖池(literal pool)的開始

            通常ARM匯編編譯器把數(shù)據(jù)緩沖池放在代碼段的最后面,即下一個代碼段開始之前,或者END偽操作之前。

            當(dāng)程序中使用LDFD之類的指令時,數(shù)據(jù)緩沖池的使用可能越界。這時可以使用LTORG偽操作定義數(shù)據(jù)緩沖池,已越界發(fā)生。通常大的代碼段可以使用多個數(shù)據(jù)緩沖池。

            LTORG偽操作通常放在無條件跳轉(zhuǎn)指令之后,或者子程序返回指令之后,這樣處理器就不會錯誤地將數(shù)據(jù)緩沖池中的數(shù)據(jù)當(dāng)作指令來執(zhí)行。

            匯編控制( Assembly Control )偽操作
            匯編控制偽操作用于控制匯編程序的執(zhí)行流程,常用的匯編控制偽操作包括以下幾條:
            — IF 、 ELSE 、 ENDIF
            — WHILE 、 WEND
            — MACRO 、 MEND
            — MEXIT
            1、 IF、ELSE、ENDIF
            語法格式:
            IF 邏輯表達(dá)式
            指令序列 1
            ELSE
            指令序列 2
            ENDIF
            IF 、 ELSE 、 ENDIF 偽操作能根據(jù)條件把一段源代碼包括在匯編程序內(nèi)或者將其排除在程序之外。[是IF偽操作的同義詞,|是ELSE偽操作的同義詞,]是ENDIF偽操作的同義詞。
            IF 、 ELSE 、 ENDIF 偽指令可以嵌套使用。
            使用示例:
            MACRO
            MOV_PC_LR
            [ THUMBCODE
            bx lr
            |
            mov pc,lr
            ]
            MEND
            2、 WHILE、WEND
            語法格式:
            WHILE 邏輯表達(dá)式
            指令序列
            WEND
            WHILE 、 WEND 偽操作能根據(jù)條件重復(fù)匯編相同的或者幾乎相同的一段源代碼。 WHILE 、 WEND 偽操作可以嵌套使用。
            使用示例:
            GBLA Counter ;聲明一個全局的算術(shù)變量,變量名為 counter
            counter SETA 3 ;設(shè)置循環(huán)計數(shù)變量counter初始值為3
            WHILE counter <=10 ;由counter控制循環(huán)執(zhí)行的次數(shù)
            counter SETA counter+1 ;將循環(huán)計數(shù)變量加1
            ;代碼 ;代碼
            WEND

            3、 MACRO、MEND
            語法格式:
            MACRO
            [$ label] macroname{ $ parameter1, $ parameter,…… }
            指令序列
            MEND
            MACRO偽操作標(biāo)識宏定義的開始,MEND標(biāo)識宏定義的結(jié)束。用MACRO及MEND定義一段代碼,稱為宏定義體,這樣在程序中就可以通過宏指令多次調(diào)用該代碼段。
            其中, $ label在宏指令被展開時,label會被替換成相應(yīng)的符號,通常是一個標(biāo)號。在一個符號前使用$表示程序被匯編時將使用相應(yīng)的值來替代$后的符號。
            macroname為所定義的宏的名稱。
            $parameter為宏指令的參數(shù)。當(dāng)宏指令被展開時將被替換成相應(yīng)的值,類似于函數(shù)中的形式參數(shù),可以在宏定義時為參數(shù)指定相應(yīng)的默認(rèn)值。
            宏指令的使用方式和功能與子程序有些相似,子程序可以提供模塊化的程序設(shè)計、節(jié)省存儲空間并提高運行速度。但在使用子程序結(jié)構(gòu)時需要保護(hù)現(xiàn)場,從而增加了系統(tǒng)的開銷,因此,在代碼較短且需要傳遞的參數(shù)較多時,可以使用宏匯編技術(shù)。
            首先使用MACRO和MEND等偽操作定義宏。包含在 MACRO 和 MEND 之間的代碼段稱為宏定義體,在MACRO偽操作之后的一行聲明宏的原型(包含宏名、所需的參數(shù)),然后就可以在匯編程序中通過宏名來調(diào)用它。在源程序被匯編時,匯編器將宏調(diào)用展開,用宏定義體代替源程序中的宏定義的名稱,并用實際參數(shù)值代替宏定義時的形式參數(shù)。
            宏定義中的$label是一個可選參數(shù)。當(dāng)宏定義體中用到多個標(biāo)號時,可以使用類似$label.$internallabel的標(biāo)號命名規(guī)則使程序易讀。
            MACRO 、 MEND 偽操作可以嵌套使用。
            使用示例:
            MACRO
            $HandlerLabel HANDLER $HandleLabel ;宏的名稱為HANDLER,有1個參數(shù)$HandleLabel

            $HandlerLabel
            sub sp,sp,#4 ;decrement sp(to store jump address)
            stmfd sp!,{r0} ;PUSH the work register to stack(lr does not push because it return to original address)
            ldr r0,=$HandleLabel;load the address of HandleXXX to r0
            ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
            str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
            ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)
            MEND
            ;在程序中調(diào)用該宏
            HandlerFIQ HANDLER HandleFIQ ;通過宏的名稱HANDLER調(diào)用宏,其中宏的標(biāo)號為HandlerFIQ,參數(shù)為HandleFIQ
            HandlerIRQ HANDLER HandleIRQ
            HandlerUndef HANDLER HandleUndef
            HandlerSWI HANDLER HandleSWI
            HandlerDabort HANDLER HandleDabort
            HandlerPabort HANDLER HandlePabort
            ;程序被匯編后,宏展開的結(jié)果
            HandlerFIQ
            sub sp,sp,#4 ;decrement sp(to store jump address)
            stmfd sp!,{r0} ;PUSH the work register to stack(lr does not push because it return to original address)
            ldr r0,=HandleFIQ;load the address of HandleXXX to r0
            ldr r0,[r0] ;load the contents(service routine start address) of HandleXXX
            str r0,[sp,#4] ;store the contents(ISR) of HandleXXX to stack
            ldmfd sp!,{r0,pc} ;POP the work register and pc(jump to ISR)

            b HandlerUndef ;handler for Undefined mode
            b HandlerSWI ;handler for SWI interrupt
            b HandlerPabort ;handler for PAbort
            b HandlerDabort ;handler for DAbort
            b . ;reserved
            b HandlerIRQ ;handler for IRQ interrupt
            b HandlerFIQ ;handler for FIQ interrupt

            4、 MEXIT
            語法格式:
            MEXIT
            MEXIT 用于從宏定義中跳轉(zhuǎn)出去。
            信息報告?zhèn)尾僮?br />ASSERT 斷言錯誤偽操作;
            INFO 匯編診斷信息顯示偽操作;
            OPT 設(shè)置列表選項偽操作;
            TTL及SUBT 用于在列表文件每一項的開頭插入一個標(biāo)題和子標(biāo)題



            關(guān)鍵詞: ARM匯編語言偽操

            評論


            技術(shù)專區(qū)

            關(guān)閉