日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

arm 匯編指令 積累

 望穿墻 2013-02-16

arm 匯編指令 積累

1115人閱讀 評(píng)論(0) 收藏 舉報(bào)

一、ldr的確是個(gè)復(fù)雜的指令,現(xiàn)總結(jié)一下:
                 首先要判斷我們用的是ldr arm指令還是偽指令。 當(dāng)我們用的是arm指令時(shí),它的作用不是向寄存器里加載立即數(shù),而是將某個(gè)地址里     的內(nèi)容加載到寄存器。而偽指令ldr的作用就是向寄存器里加載立即數(shù)。
                (1) ldr偽指令
                    ldr偽指令的格式是 ldr Rn, =expr
                    其中,expr是要加載到Rn中的內(nèi)容,一般可以是立即數(shù)或者label。
                   如果expr可以用8bit數(shù)據(jù)向右移偶數(shù)位得到,那么這條偽指令就被編譯器翻譯成mov指令。具體的移位情況可以去查閱資料。反之如果立即數(shù)很大,超過了12bit的表示范疇,那么就不能用一條mov指令了,畢竟arm指令最大只有32bit的空間可用(RISC的arm所有的指令長(zhǎng)度是一致的,效率較高,當(dāng)然我們并不關(guān)心16bit的thumb指令)。如果不能用一條32bit的指令乘下來,那么就只能另辟蹊徑了,新開一段緩沖,將立即數(shù)expr放到里面,然后將其地址(暫時(shí)標(biāo)記為addr)拿來使用:
                 ldr Rn, addr
                   xxx (xxx就是expr)
                   xxx

                由于編譯器一般來說新安排的存儲(chǔ)這個(gè)立即數(shù)expr的緩沖的位置是在相應(yīng)代碼的附近(這個(gè)應(yīng)該可以控制,好像是使用.ltorg偽指令)。我們從addr地址加載數(shù)據(jù)到Rn不就可以了。

               (2)ldr arm 指令
                就是將一個(gè)地址的內(nèi)容加載到寄存器。不能用mov,因?yàn)閍rm里的mov只是在寄存器之間傳輸數(shù)據(jù),不支持在寄出器和memory之間傳遞數(shù)據(jù)。因此就出現(xiàn)了ldr/str指令。如ldr Rn, addr,注意這里的addr的值也是有限制的。這個(gè)label應(yīng)該距離當(dāng)前指令的距離不超過4k。因?yàn)槲覀冎纋abel在具體使用的時(shí)候應(yīng)該是被翻譯成了相對(duì)偏移,如果這個(gè)label長(zhǎng)度不超過12bit,那么就不應(yīng)超過4k,我們可以這樣做:
                 ldr pc, _start_armboot
                 _start_armboot: .word arm_startboot
                 這樣label _start_armboot就在指令下方,因此肯定是合法的。

 

                  ldr r0, [r1, #4] 的含義就是把r1+4 這個(gè)地址處的DOWRD 加載到r0,而尋址后,r1 的內(nèi)容并不改變。

                  ldr r0, [r1, #4]!  這種變址方式有點(diǎn)類似于++i的含義,尋址前先對(duì)基地址寄存器進(jìn)行運(yùn)算,然后尋址. 其基本的語法是在尋址符[]后面加上一個(gè)"!" 來表示

二、.world

            說說這個(gè) .word 的作用。

           word expression 就是在當(dāng)前位置放一個(gè) word 型的值,這個(gè)值就是 expression
          舉例來說,

         _rWTCON:  
        
.word 0x15300000

         就是在當(dāng)前地址,即 _rWTCON 處放一個(gè)值 0x15300000
          
不是把地址0x1530 0000 上的內(nèi)容傳遞到r1,是把地址_rWTCON上的內(nèi)容放到r1,而地址_rWTCON上的內(nèi)容是0x15300000。實(shí)際上就是把r1設(shè)置為0x15300000

三 bic

             BIC(位清除)指令對(duì) Rn 中的值 和 Operand2 值的反碼 按位進(jìn)行邏輯“與”運(yùn)算。 (注意:ARM官方網(wǎng)站有誤, 寫的是補(bǔ)碼)
             BIC 是 邏輯”與非” 指令, 實(shí)現(xiàn)的 Bit Clear的功能

            舉例:
             BIC     R0,   R0  , #0xF0000000
            #將 R0  高4位清零

            BIC    R1,  R1,   #0x0F
            #將R1   低4位清0
            RSB 反向減法
            Rn, Operand2
            RSB(反向減法)指令可從 Operand2 中的值減去 Rn 中的值。
            這是很有用的,因?yàn)橛辛嗽撝噶?,Operand2 的選項(xiàng)范圍就會(huì)更大。

            例如:
            RSB r4, r4, #1280
            從1280中減去 R4

            RSB R4, R0, #0×46
            從0×46 中 減去 R0, 放入R4

四、ADR

           ADR的定義為:小范圍的地址讀取偽指令,ADR指令將基于PC相對(duì)偏移的地址值讀取到寄存器中,在編譯源程序時(shí)ADR偽指令被編譯器 替換成一條合適的指令。通常,編譯器用一條ADD指令或SUB指令來實(shí)現(xiàn)該ADR偽指令的功能,若不能用一條指令實(shí)現(xiàn),剛產(chǎn)生錯(cuò)誤。

在如上的定義中,有兩個(gè)關(guān)鍵信息:⑴將基于PC相對(duì)偏移的地址值讀取到寄存器中;⑵被編譯器替換成一條合適的指令。ADR指令只能將地址值讀取到寄存器中,而不能是其它的立即數(shù),并用只能用一條指令。

           如果在匯編程序中使用ADR R1,ResetHandel語句,其中ResetHandel是匯編程序中的一個(gè)標(biāo)簽,此條偽指令的作用是把ResetHandel標(biāo)簽所在的指令地址 讀取到寄存器R0中

          根據(jù)上面的分析,可以看到,編譯器在編譯的時(shí)候把ADR偽指令編譯成一個(gè)ADD R1,PC,Immediate指令,其中Immediate是一個(gè)立即數(shù),數(shù)值是ResetHandel語句和此條偽指令之間的差值,由編譯器自動(dòng)算 出。由于立即數(shù)尋址的約束,這個(gè)Immediate存在一定的約束,所以會(huì)出現(xiàn)定義中所說的不能用一條指令實(shí)現(xiàn)。

五、ldmia  和 stmia

           所有的示例指令執(zhí)行前:
mem32[0x1000C] = 0x04
mem32[0x10008] = 0x03
mem32[0x10004] = 0x02
mem32[0x10000] = 0x01
r0 = 0x00010010
r1 = 0x00000000
r3 = 0x00000000
r4 = 0x00000000
1) ldmia r0!, {r1-r3} 2) ldmib r0!, {r1-r3}
執(zhí)行后:                      執(zhí)行后:
r0 = 0x0010001C    r0 = 0x0010001C
r1 = 0x01                   r1 = 0x02
r2 = 0x02                   r2 = 0x03
r3 = 0x03                   r3 = 0x04
至于DA 和DB 的模式,和IA / IB 是類似的,不多說了。
最后要說的是,使用ldm 和stm指令對(duì)進(jìn)行寄存器組的保護(hù)是很常見和有效的功能。配對(duì)方案:
stmia / ldmdb
stmib / ldmda
stmda / ldmib
stmdb / ldmia
繼續(xù)來看兩個(gè)例子:
執(zhí)行前:
r0 = 0x00001000
r1 = 0x00000003
r2 = 0x00000002
r3 = 0x00000001
執(zhí)行的指令:
stmib r0!, {r1-r3}
mov r1, #1 ; These regs have been modified
mov r2, #2
mov r3, #3
當(dāng)前寄存器狀態(tài):
r0 = 0x0000100C
r1 = 0x00000001
r2 = 0x00000002
r3 = 0x00000003
ldmia r0!, {r1-r3}
最后的結(jié)果:
r0 = 0x00001000
r1 = 0x00000003
r2 = 0x00000002
r3 = 0x00000001
另外,我們還可以利用這個(gè)指令對(duì)完成內(nèi)存塊的高效copy:
loop
ldmia r9!, {r0-r7}
stmia r10!, {r0-r7}
cmp r9, r11
bne loop

六、CMP

         CMP指令的格式為:
         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)志位。標(biāo)志位表示的是操作數(shù)1與操作數(shù)2的關(guān)系(大、小、相等),例如,當(dāng)操作數(shù)1大于操作操作數(shù)2,則此后的有GT 后綴的指令將可以執(zhí)行。
        指令示例:
        CMP R1,R0 ;將寄存器R1的值與寄存器R0的值相減,并根據(jù)結(jié)果設(shè)置CPSR的標(biāo)志位
        CMP R1,#100 ;將寄存器R1的值與立即數(shù)100相減,并根據(jù)結(jié)果設(shè)置CPSR的標(biāo)志位

 

        cmp r0, #0
    beq 1f ; 如果r0==0那么向前跳轉(zhuǎn)到B處執(zhí)行
    bne 1b ; 否則向后跳轉(zhuǎn)到A處執(zhí)行1: ;
    1b,1f里的b和f表示backward和forward,1表示局部標(biāo)簽1

 

     TST     R0, #0X8
    BNE    SuspendUp ;BNE指令 是“不相等(或不為0)跳轉(zhuǎn)指令 ”:

    LDR   R1,#0x00000000

    先進(jìn)行and運(yùn)算,如果R0的第四位不為1,則結(jié)果為零,則設(shè)置zero=1(繼續(xù)下面的LDR指令);

    否則,zero=0(跳到SuspendUp處執(zhí)行)

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多