新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > arm匯編—ldr加載指令,ldr偽指令

        arm匯編—ldr加載指令,ldr偽指令

        作者: 時間:2016-11-09 來源:網絡 收藏
        1,ldr加載指令

        LDR指令的格式為:
        LDR{條件} 目的寄存器,<存儲器地址>
        LDR指令用亍從存儲器中將一個32位的字數據傳送到目的寄存器中。該指令通常用亍從存儲器
        中讀取32位的字數據到通用寄存器,然后對數據迕行處理。當程序計數器PC作為目的寄存器時,
        指令從存儲器中讀取的字數據被當作目的地址,從而可以實現程序流程的跳轉。該指令在程序設
        計中比較常用,丏尋址方式靈活多樣,請讀者認真掌握。
        指令示例:
        LDR R0,[R1] ;將存儲器地址為R1的字數據讀入寄存器R0。
        LDR R0,[R1,R2] ;將存儲器地址為R1+R2的字數據讀入寄存器R0。
        LDR R0,[R1,#8] ;將存儲器地址為R1+8的字數據讀入寄存器R0。
        LDR R0,[R1,R2]!;將存儲器地址為R1+R2的字數據讀入寄存器R0,幵將新地址R1+R2寫入R1。
        LDR R0,[R1,#8]! ;將存儲器地址為R1+8的字數據讀入寄存器R0,幵將新地址R1+8寫入R1。
        LDR R0,[R1],R2 ;將存儲器地址為R1的字數據讀入寄存器R0,幵將新地址R1+R2寫入R1。
        LDR R0,[R1,R2,LSL#2]! ;將存儲器地址為R1+R2×4的字數據讀入寄存器R0,并將新地址R1+R2×4寫入R1。
        LDR R0,[R1],R2,LSL#2 ;將存儲器地址為R1的字數據讀入寄存器R0,幵將新地址R1+R2×4寫入R1。”

        ARM是RISC結構,數據從內存到CPU乊間的移勱叧能通過L/S指令來完成,也就是ldr/str指令。
        比如想把數據從內存中某處讀取到寄存器中,叧能使用ldr
        比如:
        ldr r0, 0x12345678
        就是把0x12345678返個地址中的值存放到r0中。

        2,ldr偽指令
        ARM指令集中,LDR通常都是作加載指令的,但是它也可以作偽指令。
        LDR偽指令的形式是“LDR Rn,=expr”。

        例子:
        COUNT EQU 0x43100
        ……
        LDR R1,=COUNT
        MOV R0,#0
        STR R0,[R1]

        COUNT是我們定義的一個變量,地址為0x43100。這中定義方法在匯編語言中是很常見的,如果使用過單片機的話,應該都熟悉這種用法。
        LDR R1,=COUNT是將COUNT這個變量的地址,也就是0x43100放到R1中。
        MOV R0,#0是將立即數0放到R0中。最后一句STR R0,[R1]是一個典型的存儲指令,將R0中的值放到以R1中的值為地址的存儲單元去。實際就是將0放到地址為0x43100的存儲單元中去。可 見這三條指令是為了完成對變量COUNT賦值。用三條指令來完成對一個變量的賦值,看起來有點不太舒服。這可能跟ARM的采用RISC有關。

        下面還有一個例子
        ;將COUNT的值賦給R0
        LDR R1,=COUNT
        LDR R0,[R1]
        LDR R1,=COUNT這條偽指令,是怎樣完成將COUNT的地址賦給R1,有興趣的可以看它編譯后的結果。這條指令實際上會編譯成一條LDR指令和一條DCD偽指令。

        2,LDR 的兩種用法
        1)LDR pc, =MyHandleIRQ 表示將MyHandleIRQ符號放入pc寄存器中
        2)LDR PC,MyHandleIRQ 表示將讀取存儲器中MyHandleIRQ符號所表示的地址中的值,及需要多讀一次存儲器。

        在代碼中:
        start:
        ldr pc,=MyHandleReset @jump to HandleReset
        ldr pc,=MyHandleUndef @jump to HandleUndef
        ldr pc,=MyHandleSWI @jump to HandleSWI
        ldr pc,=MyHandleIabort @jump to HandleIabort
        ldr pc,=MyHandleDabort @jump to HandleDabort
        nop
        ldr pc,=MyHandleIRQ @jump to HandleIRQ <=之前出錯的一行
        ldr pc,=MyHandleFIQ @jump to HandleFIQ

        @MyHandleIRQ: .word OS_CPU_IRQ_ISR
        MyHandleIRQ:
        sub lr, lr, #4 @ to calculate the return address
        stmdb sp!, {r0-r12,lr}
        ldr lr, =int_return @ restore the return address
        ldr pc, =int_handle @ call for the interrupt handler
        在“之前出錯的一行”處,如果改成“ldr pc,MyHandleIRQ”當中斷來臨時,無法進行中斷處理。

        另一種情況是正確的,注意體會:
        start:
        ldr pc,=MyHandleReset @jump to HandleReset
        ldr pc,=MyHandleUndef @jump to HandleUndef
        ldr pc,=MyHandleSWI @jump to HandleSWI
        ldr pc,=MyHandleIabort @jump to HandleIabort
        ldr pc,=MyHandleDabort @jump to HandleDabort
        nop
        ldr pc,MyHandleIRQ @jump to HandleIRQ <=之前出錯的一行
        ldr pc,=MyHandleFIQ @jump to HandleFIQ

        MyHandleIRQ: .word OS_CPU_IRQ_ISR
        @MyHandleIRQ:
        @ sub lr, lr, #4 @ to calculate the return address
        @ stmdb sp!, {r0-r12,lr}
        @ ldr lr, =int_return @ restore the return address
        @ ldr pc, =int_handle @ call for the interrupt handler
        因為當中斷來臨時,還需要去MyHandleIRQ處把OS_CPU_IRQ_ISR取出,即多取一次存儲器。

        本文引用地址:http://www.104case.com/article/201611/317896.htm


        評論


        技術專區

        關閉
        主站蜘蛛池模板: 灵丘县| 浏阳市| 永福县| 乡宁县| 西昌市| 邹平县| 西盟| 星子县| 凭祥市| 南郑县| 乌鲁木齐市| 广饶县| 永春县| 海林市| 瑞安市| 衢州市| 朔州市| 定兴县| 微博| 息烽县| 甘洛县| 建昌县| 西贡区| 武鸣县| 巴彦淖尔市| 中山市| 富阳市| 乐山市| 长海县| 福泉市| 娱乐| 洪江市| 宜川县| 封丘县| 卓尼县| 浦江县| 苍南县| 平阳县| 中牟县| 常山县| 无棣县|