国产无码免费,人妻口爆,国产V在线,99中文精品7,国产成人无码AA精品一,制度丝袜诱惑av,久久99免费麻辣视频,蜜臀久久99精品久久久久久酒店
        訂閱
        糾錯(cuò)
        加入自媒體

        技術(shù)文章:從0開(kāi)始學(xué)ARM-ARM匯編指令其實(shí)很簡(jiǎn)單

        學(xué)習(xí)ARM,就必須要學(xué)習(xí)ARM指令,ARM指令是CPU提供給我們的接口,是我們打開(kāi)CPU這個(gè)潘多拉魔盒的鑰匙。

        ARM指令有很多,為了讓大家能快速上手,一口君整理了一些對(duì)我們最有幫助的指令。keil軟件的操作,可以參考第一章。

        讓我們開(kāi)始吧!

        0.指令分類(lèi)

        數(shù)據(jù)處理指令數(shù)據(jù)處理指令可分為數(shù)據(jù)傳送指令、算術(shù)邏輯運(yùn)算指令和比較指令等。

        數(shù)據(jù)傳送指令用于在寄存器和存儲(chǔ)器之間進(jìn)行數(shù)據(jù)的雙向傳輸。

        算術(shù)邏輯運(yùn)算指令完成常用的算術(shù)與邏輯的運(yùn)算,該類(lèi)指令不但將運(yùn)算結(jié)果保存在目的寄存器中,同時(shí)更新CPSR中的相應(yīng)條件標(biāo)志位。

        一、MOV指令1、MOV

        語(yǔ)法:

        MOV{條件}{S}   目的寄存器,源操作數(shù)

        功能:MOV指令完成從另一個(gè)寄存器、被移位的寄存器或?qū)⒁粋(gè)立即數(shù)加載到目的寄存器。其中S選項(xiàng)決定指令的操作是否影響CPSR中條件標(biāo)志位的值,當(dāng)沒(méi)有S時(shí)指令不更新CPSR中條件標(biāo)志位的值。

        指令示例:

        MOV r0, #0x1 ;將立即數(shù)0x1傳送到寄存器R0
        MOV R1,R0  ;將寄存器R0的值傳送到寄存器R1
        MOV PC,R14   ;將寄存器R14的值傳送到PC,常用于子程序返回
        MOV R1,R0,LSL #3  ;將寄存器R0的值左移3位后傳送到R1

        【注:不區(qū)分大小寫(xiě)】

        思考,為什么以下賦值出錯(cuò)?

        MOV R0,#0xfff

        錯(cuò)誤log

        要想搞懂這個(gè)問(wèn)題,我們需要了解什么是立即數(shù)。

        2. 什么是立即數(shù)?

        立即數(shù)是由 0-255之間的數(shù)據(jù)循環(huán)右移偶數(shù)位生成。

        判斷規(guī)則如下:

        把數(shù)據(jù)轉(zhuǎn)換成二進(jìn)制形式,從低位到高位寫(xiě)成4位1組的形式,最高位一組不夠4位的,在最高位前面補(bǔ)0。數(shù)1的個(gè)數(shù),如果大于8個(gè)肯定不是立即數(shù),如果小于等于8進(jìn)行下面步驟。如果數(shù)據(jù)中間有連續(xù)的大于等于24個(gè)0,循環(huán)左移2的倍數(shù),使高位全為0。找到最高位的1,去掉前面最大偶數(shù)個(gè)0。找到最低位的1,去掉后面最大偶數(shù)個(gè)0。數(shù)剩下的位數(shù),如果小于等于8位,那么這個(gè)數(shù)就是立即數(shù),反之就不是立即數(shù)。

        而例子中的數(shù)是0xfff,我們來(lái)看下他的二進(jìn)制:

        0000 0000 0000 0000 0000 1111 1111 1111

        按照上述規(guī)則,我們最終操作結(jié)果如下:

        1111 1111 1111

        可以看到剩余的位數(shù)大于8個(gè),所以該數(shù)不是立即數(shù)。為什么立即數(shù)會(huì)有這么個(gè)限定?我們需要從MOV這條指令的機(jī)器碼來(lái)說(shuō)起。

        3. MOV機(jī)器碼

        讓我們執(zhí)行下面代碼:

        AREA Example,CODE,READONLY    ;聲明代碼段Example
        ENTRY ;程序入口
        Start
        //測(cè)試代碼,添加在以下位置即可,后面不再貼完整代碼                                
        mov r1,#0x80000001  
        OVER
        END

        然后點(diǎn)擊debug按鈕,查看對(duì)應(yīng)的機(jī)器碼:

        機(jī)器指令

        得到mov r1,#0x80000001指令的機(jī)器碼是E3A01106

        我們來(lái)分析這個(gè)機(jī)器碼。

        MOV機(jī)器指令格式

        用ARM指令助記符表示為:


        每個(gè)域的含義如下:

        1) {

        指令允許執(zhí)行的條件編碼。花括號(hào)表示此項(xiàng)可缺省。

        ARM指令的一個(gè)重要特點(diǎn)是可以條件執(zhí)行,每條ARM指令的條件碼域包含4位條件碼,共16種。幾乎所有指令均根據(jù)CPSR中條件碼的狀態(tài)和指令條件碼域的設(shè)置有條件的執(zhí)行。當(dāng)指令執(zhí)行條件滿(mǎn)足時(shí),指令被執(zhí)行,否則被忽略。指令條件碼及其助記符后綴表示參見(jiàn)下表。

        指令的條件碼

        每種條件碼可用兩個(gè)字符表示,這兩個(gè)字符可以作為后綴添加在指令助記符的后面和指令同時(shí)使用。

        例如:跳轉(zhuǎn)指令B可以加上后綴EQ變?yōu)锽EQ,表示“相等則跳轉(zhuǎn)”,即當(dāng)CPSR中的Z標(biāo)志置位時(shí)發(fā)生跳轉(zhuǎn)。

        2)

        指令編碼的助記符;

        3) {S} :條件碼設(shè)置域

        這是一個(gè)可選項(xiàng),當(dāng)在指令中設(shè)置{S}域時(shí),指令執(zhí)行的結(jié)果將會(huì)影響程序狀態(tài)寄存器CPSR中相應(yīng)的狀態(tài)標(biāo)志。例如:

        ADD R0,R1,R2;R1與R2的和存放到R0寄存器中,不影響狀態(tài)寄存器
         ADDS R0,R1,R2; 執(zhí)行加法的同時(shí)影響狀態(tài)寄存器

        指令中比較特殊的是CMP指令,它不需要加S后綴就默認(rèn)地根據(jù)計(jì)算結(jié)構(gòu)更改程序狀態(tài)寄存器

        4)

        ARM指令中的目的操作數(shù)總是一個(gè)寄存器。如果與第一操作數(shù)寄存器相同,也必須要指明,不能缺省。

        5)

        ARM指令中的第一操作數(shù)也必須是個(gè)寄存器。

        6)

        在第二操作數(shù)中可以是寄存器、內(nèi)存存儲(chǔ)單元或者立即數(shù)。

        如果是立即數(shù):

        bit:[11-8]表示操作數(shù)向左移動(dòng)的位數(shù)/2,
        bit:[7-0]表示最終的操作數(shù)

        根據(jù)MOV指令格式,我們分析各個(gè)位域的值:

        bite含義1110Cond忽略00  1
        1101opcode0s 命令不含S0000rn,沒(méi)有源寄存器為00001rd   目的結(jié)存器R00001shifter0000 0110操作數(shù)

        立即數(shù)0x80000001二進(jìn)制為:

        1000 0000 0000 0000 0000 0000 0000 0001

        循環(huán)左移2位后得到以下結(jié)果:

        00 0000 0000 0000 0000 0000 0000 0001 10

        所以shifter的值為2/2=1,操作數(shù)的值為0000 0110。

        二、移位操作

        ARM微處理器支持?jǐn)?shù)據(jù)的移位操作,移位操作在ARM指令集中不作為單獨(dú)的指令使用,它只能作為指令格式中是一個(gè)字段,在匯編語(yǔ)言中表示為指令中的選項(xiàng)。移位操作包括如下6種類(lèi)型,ASL和LSL是等價(jià)的,可以自由互換:

        1) LSL(或ASL)邏輯(算術(shù))左移

        尋址格式:

        通用寄存器,LSL(或ASL) 操作數(shù)  

        完成對(duì)通用寄存器中的內(nèi)容進(jìn)行邏輯(或算術(shù))的左移操作,按操作數(shù)所指定的數(shù)量向左移位,低位用零來(lái)填充。其中,操作數(shù)可以是通用寄存器,也可以是立即數(shù)(0~31)。如:

        MOV    R0, R1, LSL#2  ;將R1中的內(nèi)容左移兩位后傳送到R0中。
        2) LSR邏輯右移

        尋址格式:

        通用寄存器,LSR 操作數(shù)

        完成對(duì)通用寄存器中的內(nèi)容進(jìn)行右移的操作,按操作數(shù)所指定的數(shù)量向右移位,左端用零來(lái)填充。其中,操作數(shù)可以是通用寄存器,也可以是立即數(shù)(0~31)。如:

        MOV    R0, R1, LSR #2  ;將R1中的內(nèi)容右移兩位后傳送到R0中,左端用零來(lái)填充。
        3) ASR算術(shù)右移

        尋址格式:

        通用寄存器,ASR 操作數(shù)    

        完成對(duì)通用寄存器中的內(nèi)容進(jìn)行右移的操作,按操作數(shù)所指定的數(shù)量向右移位,左端用第31位的值來(lái)填充。其中,操作數(shù)可以是通用寄存器,也可以是立即數(shù)(0~31)。如:

        MOV    R0, R1, ASR #2  ;將R1中的內(nèi)容右移兩位后傳送到R0中,左端用第31位的值來(lái)填充。
        4) ROR循環(huán)右移

        尋址格式:

        通用寄存器,ROR 操作數(shù)      

        完成對(duì)通用寄存器中的內(nèi)容進(jìn)行循環(huán)右移的操作,按操作數(shù)所指定的數(shù)量向右循環(huán)移位,左端用右端移出的位來(lái)填充。其中,操作數(shù)可以是通用寄存器,也可以是立即數(shù)(0~31)。顯然,當(dāng)進(jìn)行32位的循環(huán)右移操作時(shí),通用寄存器中的值不改變。如:

        MOV    R0, R1, ROR #2  ;將R1中的內(nèi)容循環(huán)右移兩位后傳送到R0中。
        5) RRX帶擴(kuò)展的循環(huán)右移

        尋址格式:

        通用寄存器,RRX 操作數(shù)      

        完成對(duì)通用寄存器中的內(nèi)容進(jìn)行帶擴(kuò)展的循環(huán)右移的操作,按操作數(shù)所指定的數(shù)量向右循環(huán)移位,左端用進(jìn)位標(biāo)志位C來(lái)填充。其中,操作數(shù)可以是通用寄存器,也可以是立即數(shù)(0~31)。如:

        MOV    R0, R1, RRX #2  ;將R1中的內(nèi)容進(jìn)行帶擴(kuò)展的循環(huán)右移兩位后傳送到R0中。
        舉例; 第二操作數(shù) 寄存器移位操作, 5種移位方式, 9種語(yǔ)法
        ;邏輯左移
        mov r0, #0x1
        mov r1, r0, lsl #1    ; 移位位數(shù)1-31肯定合法

        mov r0, #0x2
        mov r1, r0, lsr #1    ; 邏輯右移
        mov r0, #0xffffffff
        mov r1, r0, asr #1    ; 算術(shù)右移符號(hào)位不變, 次高位補(bǔ)符號(hào)位
        mov r0, #0x7fffffff
        mov r1, r0, asr #1
           mov r0, #0x7fffffff
        mov r1, r0, ror #1 ; 循環(huán)右移
           mov r0, #0xffffffff
        mov r1, r0, rrx ; 唯一不需要指定循環(huán)位數(shù)的移位方式
        ;帶擴(kuò)展的循環(huán)右移
        ;C標(biāo)志位進(jìn)入最高位,最低位進(jìn)入C 標(biāo)志位
        ; 移位值可以是另一個(gè)寄存器的值低5bit, 寫(xiě)法如下
        mov r2, #1
        mov r0, #0x1
        mov r1, r0, lsl r2    ; 移位位數(shù)1-31肯定合法
        mov r0, #0xffffffff
        mov r1, r0, asr r2    ; 算術(shù)右移符號(hào)位不變, 次高位補(bǔ)符號(hào)位
        mov r0, #0x7fffffff
        mov r1, r0, asr r2
           mov r0, #0x7fffffff
        mov r1, r0, ror r2 ; 循環(huán)右移

        上述結(jié)果不再截圖,讀者可以自行拷貝到keil中進(jìn)行debug,查看寄存器中值以及符號(hào)位的變化。

        三、CMP比較指令

        語(yǔ)法

        CMP{條件} 操作數(shù)1,操作數(shù)2

        CMP指令用于把一個(gè)寄存器的內(nèi)容和另一個(gè)寄存器的內(nèi)容或立即數(shù)進(jìn)行比較,同時(shí)更新CPSR中條件標(biāo)志位的值。該指令進(jìn)行一次減法運(yùn)算,但不存儲(chǔ)結(jié)果,只更改條件標(biāo)志位。cmp是做一次減法,并不保存結(jié)果,僅僅用來(lái)產(chǎn)生一個(gè)邏輯,體現(xiàn)在改變cpsr相應(yīng)的condition位。

        標(biāo)志位表示的是操作數(shù)1與操作數(shù)2的關(guān)系(大、小、相等),指令示例:

        CMP R1,R0   ;將寄存器R1的值與寄存器R0的值相減,并根據(jù)結(jié)果設(shè)置CPSR的標(biāo)志位
        CMP R1,#100 ;將寄存器R1的值與立即數(shù)100相減,并根據(jù)結(jié)果設(shè)置CPSR的標(biāo)志位
        四、TST條件指令

        語(yǔ)法

        TST{條件}  操作數(shù)1,操作數(shù)2

        TST指令用于把一個(gè)寄存器的內(nèi)容和另一個(gè)寄存器的內(nèi)容或立即數(shù)進(jìn)行按位的與運(yùn)算,并根據(jù)運(yùn)算結(jié)果更新CPSR中條件標(biāo)志位的值。操作數(shù)1是要測(cè)試的數(shù)據(jù),而操作數(shù)2是一個(gè)位掩碼,根據(jù)測(cè)試結(jié)果設(shè)置相應(yīng)標(biāo)志位。當(dāng)位與結(jié)果為0時(shí),EQ位被設(shè)置。指令示例

         TST   R1,#%1  ;用于測(cè)試在寄存器R1中是否設(shè)置了最低位(%表示二進(jìn)制數(shù))。
        比較指令和條件執(zhí)行舉例

        例1:找出三個(gè)寄存器中數(shù)據(jù)最大的數(shù)

        mov r0, #3
        mov r1, #4
        mov r2, #5
        cmp r1,r0
        movgt r0,r1
        cmp r2,r0
        movgt r0,r2

        例2:求兩個(gè)數(shù)的差的絕對(duì)值

        mov r0,#9
         mov r1,#15
         cmp r0,r1
         beq stop
         subgt r0,r0,r1
         sublt r1,r1,r0

        帶條件碼的指令執(zhí)行請(qǐng)參考本篇表格《指令的條件碼》

        五、數(shù)據(jù)的處理指令A(yù)DDADD{條件}{S} 目的寄存器,操作數(shù)1,操作數(shù)2

        ADD指令用于把兩個(gè)操作數(shù)相加,并將結(jié)果存放到目的寄存器中。操作數(shù)1應(yīng)是一個(gè)寄存器,操作數(shù)2可以是一個(gè)寄存器,被移位的寄存器,或一個(gè)立即數(shù)。指令示例:

        ADD  R0,R1,R2           ;R0 = R1 + R2
        ADD  R0,R1,#256            ;R0 = R1 + 256
        ADD  R0,R2,R3,LSL#1      ;R0 = R2 + (R3 << 1)
        ADC

        注意這個(gè)指令不是射手。。。。

        除了正常做加法運(yùn)算之外,還要加上CPSR中的C條件標(biāo)志位,如果要影響CPSR中對(duì)應(yīng)位,加后綴S。

        SUB

        SUB指令的格式為:

        SUB{條件}{S} 目的寄存器,操作數(shù)1,操作數(shù)2

        SUB指令用于把操作數(shù)1減去操作數(shù)2,并將結(jié)果存放到目的寄存器中。操作數(shù)1應(yīng)是一個(gè)寄存器,操作數(shù)2可以是一個(gè)寄存器,被移位的寄存器,或一個(gè)立即數(shù)。該指令可用于有符號(hào)數(shù)或無(wú)符號(hào)數(shù)的減法運(yùn)算。

        如:

        SUB  R0,R1,R2          ;R0 = R1 - R2
        SUB  R0,R1,#256        ;R0 = R1 - 256
        SUB  R0,R2,R3,LSL#1   ;R0 = R2 - (R3 << 1)

        SBC

        除了正常做加法運(yùn)算之外,還要再減去CPSR中C條件標(biāo)志位的反碼 根據(jù)執(zhí)行結(jié)果設(shè)置CPSR對(duì)應(yīng)的標(biāo)志位AND指令的格式為:

        AND{條件}{S} 目的寄存器,操作數(shù)1,操作數(shù)2

        AND指令用于在兩個(gè)操作數(shù)上進(jìn)行邏輯與運(yùn)算,并把結(jié)果放置到目的寄存器中。操作數(shù)1應(yīng)是一個(gè)寄存器,操作數(shù)2可以是一個(gè)寄存器,被移位的寄存器,或一個(gè)立即數(shù)。該指令常用于屏蔽操作數(shù)1的某些位。如:

        AND  R0,R0,#3           ; 該指令保持R0的0、1位,其余位清零。
        ORR

        ORR指令的格式為:

        ORR{條件}{S} 目的寄存器,操作數(shù)1,操作數(shù)2

        ORR指令用于在兩個(gè)操作數(shù)上進(jìn)行邏輯或運(yùn)算,并把結(jié)果放置到目的寄存器中。操作數(shù)1應(yīng)是一個(gè)寄存器,操作數(shù)2可以是一個(gè)寄存器,被移位的寄存器,或一個(gè)立即數(shù)。該指令常用于設(shè)置操作數(shù)1的某些位。如:

        ORR  R0,R0,#3           ; 該指令設(shè)置R0的0、1位,其余位保持不變。
        BIC

        這是一個(gè)非常實(shí)用的指令,在實(shí)際寄存器操作經(jīng)常要將某些位清零,但是又不想影響其他位的值,就可以使用該命令。

        BIC指令的格式為:

        BIC{條件}{S} 目的寄存器,操作數(shù)1,操作數(shù)2

        BIC指令用于清除操作數(shù)1的某些位,并把結(jié)果放置到目的寄存器中。

        操作數(shù)1應(yīng)是一個(gè)寄存器,操作數(shù)2可以是一個(gè)寄存器,被移位的寄存器,或一個(gè)立即數(shù)。操作數(shù)2為32位的掩碼,如果在掩碼中設(shè)置了某一位,則清除這一位。未設(shè)置的掩碼位保持不變。

        如:

        BIC  R0,R0,#%1011    ; 該指令清除 R0 中的位 0、1、和 3,其余的位保持不變。
        數(shù)據(jù)處理指令舉例加法運(yùn)算 mov r0, #1
        mov r1, #2
         
        add r2, r0, r1 ; r2 = r0 + r1
        add r2, r0, #4
        add r2, r0, r1, lsl #2 ;  r2 = r0 +R1<<2; (R0 + R1*4)
        adc,64位加法運(yùn)算的實(shí)現(xiàn) ; 2. adc  64位加法 r0, r1 =  r0, r1 + r2, r3
        mov r0, #0
        mov r1, #0xffffffff
          mov r2, #0
        mov r3, #0x1
        adds r1, r1, r3 ; r1 = r1 + r3  必須加S后綴
        adc r0, r0, r2 ; r0 = r0 + r2 + c ;add  帶 擴(kuò)展的加法

        可以對(duì)比下add和adds,沒(méi)有加s的話(huà)是不會(huì)影響條件位的。

        減法; 3. sub  rd = rn - op2
        mov r0, #1
        sub r0, r0, #1 ; r0 = r0 - 1
        64位減法; 4. sbc  64位減法 r0, r1 =  r0, r1 - r2, r3
           ; cpsr c 對(duì)于加法運(yùn)算 C = 1 則代表有進(jìn)位, C = 0 無(wú)進(jìn)位
        ;   對(duì)于減法運(yùn)算 C = 1 則代表無(wú)借位, C = 0 有借位
         mov r0, #0
        mov r1, #0x0
          mov r2, #0
        mov r3, #0x1
        subs r1, r1, r3
        sbc r0, r0, r2   ;sbc  帶擴(kuò)展的減法  
        位清除 ; 5. bic   位清除
        mov r0, #0xffffffff
        bic r0, r0, #0xff       ; and r0, r0, #0xffffff00

        執(zhí)行結(jié)果

        執(zhí)行結(jié)果六、跳轉(zhuǎn)指令

        跳轉(zhuǎn)指令用于實(shí)現(xiàn)程序流程的跳轉(zhuǎn),在ARM程序中有兩種方法可以實(shí)現(xiàn)程序流程的跳轉(zhuǎn):

        使用專(zhuān)門(mén)的跳轉(zhuǎn)指令;

        直接向程序計(jì)數(shù)器PC寫(xiě)入跳轉(zhuǎn)地址值,通過(guò)向程序計(jì)數(shù)器PC寫(xiě)入跳轉(zhuǎn)地址值,可以實(shí)現(xiàn)在4GB的地址空間中的任意跳轉(zhuǎn),在跳轉(zhuǎn)之前結(jié)合使用。

        使用以下指令,可以保存將來(lái)的返回地址值,從而實(shí)現(xiàn)在4GB連續(xù)的線(xiàn)性地址空間的子程序調(diào)用。

        MOV LR,PC

        ARM指令集中的跳轉(zhuǎn)指令可以完成從當(dāng)前指令向前或向后的32MB的地址空間的跳轉(zhuǎn),包括以下4條指令:

        B        跳轉(zhuǎn)指令
        BL       帶返回的跳轉(zhuǎn)指令
        BLX      帶返回和狀態(tài)切換的跳轉(zhuǎn)指令thumb指令
        BX       帶狀態(tài)切換的跳轉(zhuǎn)指令thumb指令
        1. B 指令

        指令的格式為:

        B{條件}  目標(biāo)地址

        B指令是最簡(jiǎn)單的跳轉(zhuǎn)指令。一旦遇到一個(gè) B 指令,ARM 處理器將立即跳轉(zhuǎn)到給定的目標(biāo)地址,從那里繼續(xù)執(zhí)行。

         B label     程序無(wú)條件跳轉(zhuǎn)到標(biāo)號(hào)label處執(zhí)行
          CMP R1 ,#0
          BEQ label      當(dāng)CPSR寄存器中的Z條件碼置位時(shí),程序跳轉(zhuǎn)到標(biāo)號(hào)Label處執(zhí)行。
        2. BL 指令

        BL 指令的格式為:

         BL{條件}  目標(biāo)地址

        BL是另一個(gè)跳轉(zhuǎn)指令,但跳轉(zhuǎn)之前,會(huì)在寄存器R14中保存PC當(dāng)前值,因此,可以通過(guò)將R14 的內(nèi)容重新加載到PC中,來(lái)返回到跳轉(zhuǎn)指令之后的那個(gè)指令處執(zhí)行。該指令是實(shí)現(xiàn)子程序調(diào)用的一個(gè)基本但常用的手段。

        BL label     當(dāng)程序無(wú)條件跳轉(zhuǎn)到標(biāo)號(hào)Label處執(zhí)行時(shí),同時(shí)將當(dāng)前的PC值保存到R14中

        子函數(shù)要返回執(zhí)行以下指令即可:

        MOV PC,LR
        3. BL指令機(jī)器碼

        語(yǔ)法:

        Branch :  B{

        BL機(jī)器碼格式如下:

        b指令機(jī)器碼

        各域含義:

        域含義cond條件碼101操作碼L命令是否包含Loffset指令跳轉(zhuǎn)偏移量

        其中offset是24個(gè)bite,最高位包含一個(gè)符號(hào)位,1個(gè)單位表示偏移一條指令,所以可以尋址±2^23^條指令,即±8M條指令。

        而一條指令是4個(gè)字節(jié),所以最大尋址空間為±32MB的地址空間

        我們來(lái)看下以下代碼:

        AREA Example,CODE,READONLY  
        ENTRY ;程序入口
        Start            
        MOV R0,#0    
        MOV R1,#10
        BL ADD_SUM  
        B OVER        
        ADD_SUM
        ADD R0,R0,R1
        MOV PC,LR    
        OVER
        END

        BL機(jī)器碼

        由上圖所示:

        第6行代碼BL ADD_SUM 會(huì)跳轉(zhuǎn)到第8行,即第9行的代碼第6行的指令的機(jī)器碼是EB000000

        根據(jù)BL的機(jī)器碼我們可以得到offset的值是0x000000,也就是說(shuō)該指令跳轉(zhuǎn)本身,而根據(jù)我們的分析第6行代碼,應(yīng)該是向前跳轉(zhuǎn)2條指令,按道理offset是應(yīng)該是2,為什么是0呢?

        因?yàn)槭?級(jí)流水線(xiàn),所以pc存儲(chǔ)指令地址與正在處理指令地址之間相差8個(gè)字節(jié),pc的地址是預(yù)取指令地址,而不是正在執(zhí)行的指令的地址。

        4. 如何訪(fǎng)問(wèn)全部32-bit地址空間?

        可以手動(dòng)設(shè)置LR寄存器,然后裝載到PC中。

        MOV lr, pc
        LDR pc, =dest

        在編譯項(xiàng)目過(guò)程中,ARM連接器(linker)會(huì)自動(dòng)為長(zhǎng)跳轉(zhuǎn)(超過(guò)32Mb范圍)。

        ldr下一章會(huì)詳細(xì)詳細(xì)講解。

        舉例

        子函數(shù)多重嵌套調(diào)用,如何從子函數(shù)返回?

        area first, code, readonly
         code32
         entry
        main
         ; bl 指令, 子函數(shù)調(diào)用
         mov r0,#1
         bl child_func  
         mov r0,#2
        stop
           b stop
        child_func
        mov r1,r0
        mov r2,lr
        mov r0, #3 //<===  pc
        bl child_func_2
        mov r0,#4
        mov r0,r1
        mov lr,r2
        mov pc, lr
        child_func_2 ;葉子函數(shù)
        mov r3,r0
        mov r4,lr  ; 保存直接父函數(shù)用到的所有寄存器
        mov r0, #5
        mov r0,r3
        mov lr,r4 ;返回到直接父函數(shù)之前,把它用到的所有寄存器內(nèi)容恢復(fù)
        mov pc, lr
        end

        由上述例子所示,每調(diào)用一級(jí)子函數(shù),我們都把返回地址存入到未分組寄存器中,但是未分組寄存器畢竟是有限的,像Linux內(nèi)核函數(shù)的調(diào)用層次往往很深,通用寄存器根本不夠用,要想保存返回地址,就需要對(duì)數(shù)據(jù)進(jìn)行壓棧,那我們就要為每個(gè)模式的棧設(shè)置空間,那如何設(shè)置棧空間呢?下一篇我們繼續(xù)討論。

        聲明: 本文由入駐維科號(hào)的作者撰寫(xiě),觀點(diǎn)僅代表作者本人,不代表OFweek立場(chǎng)。如有侵權(quán)或其他問(wèn)題,請(qǐng)聯(lián)系舉報(bào)。

        發(fā)表評(píng)論

        0條評(píng)論,0人參與

        請(qǐng)輸入評(píng)論內(nèi)容...

        請(qǐng)輸入評(píng)論/評(píng)論長(zhǎng)度6~500個(gè)字

        您提交的評(píng)論過(guò)于頻繁,請(qǐng)輸入驗(yàn)證碼繼續(xù)

        • 看不清,點(diǎn)擊換一張  刷新

        暫無(wú)評(píng)論

        暫無(wú)評(píng)論

          人工智能 獵頭職位 更多
          掃碼關(guān)注公眾號(hào)
          OFweek人工智能網(wǎng)
          獲取更多精彩內(nèi)容
          文章糾錯(cuò)
          x
          *文字標(biāo)題:
          *糾錯(cuò)內(nèi)容:
          聯(lián)系郵箱:
          *驗(yàn) 證 碼:

          粵公網(wǎng)安備 44030502002758號(hào)

          主站蜘蛛池模板: 精品久久一区| 色色91| youjizzjizz| 荥阳市| 亚洲色图在线观看| 日韩精品久久| 一区二区三区国产| 青青网站| 欧美综合激情网| 涩涩AV| 国产精品美女| 马关县| 欧美色涩| 91视频?-?sebo99| 亚洲免费v片| 人妻少妇一区二区三区| 日韩综合| 国产一区二区三区在线| 德昌县| 久操精品| 99热色| 超碰日韩| 好吊AV| 乳源| 探花无码| 国产亚洲成人网站| 久在草影院| 青青草99| 国产jizz| 1024在线免费观看| 亚洲精品成人无码熟妇在线| 国产性爱网| 黄总av| 人人操人| 亚洲综合一区二区| 熟女老骚91PORN九色| 国产人妖网站| 延川县| 肥东县| 章丘市| 自拍偷拍视频网站|