ARM汇编之加载地址到寄存器

有这几种方式可以加载地址到寄存器:

  • 使用ADR汇编指令
  • 使用ADRL伪指令
  • 使用MOV32伪指令
  • 使用LDR Rd,=Label伪指令

下面介绍下ADR和DDRL这两个指令,另外两个前面的文章(ARM汇编中立即数的加载)已经有介绍过了不再重复详细介绍。

  • ADR

功能:在特定范围之内把地址加载到寄存器(并不会执行数据加载)
语法格式如下:
ADR{cond}{.W} Rd,label
其中label是一个和PC相关的表达式,并且label相对当前指令有距离的限制。同时label和ADR必须同属于一个代码段。

下面是lable相对当前指令距离限制

指令 偏移范围
A32 的ADR 一个8位值的数旋转右移偶数个位(32位范围内的)来产生
T32 32位的ADR ±4095
T32 16位的ADR 0~1020(是4的倍数的才可以)

下面是参考资料中的例子:

AREA   Jump, CODE, READONLY ; Name this block of code
        ARM                         ; Following code is A32 code 
num     EQU    2                    ; Number of entries in jump table
        ENTRY                       ; Mark first instruction to execute
start                               ; First instruction to call
        MOV    r0, #0               ; Set up the three arguments
        MOV    r1, #3
        MOV    r2, #2
        BL     arithfunc            ; Call the function
stop
        MOV    r0, #0x18            ; angel_SWIreason_ReportException
        LDR    r1, =0x20026         ; ADP_Stopped_ApplicationExit
        SVC    #0x123456            ; A32 semihosting (formerly SWI)
arithfunc                           ; Label the function
        CMP    r0, #num             ; Treat function code as unsigned
                                    ; integer
        BXHS   lr                   ; If code is >= num then return
        ADR    r3, JumpTable        ; Load address of jump table
        LDR    pc, [r3,r0,LSL#2]    ; Jump to the appropriate routine
JumpTable
        DCD    DoAdd
        DCD    DoSub
DoAdd
        ADD    r0, r1, r2           ; Operation 0
        BX     lr                   ; Return
DoSub
        SUB    r0, r1, r2           ; Operation 1
        BX     lr                   ; Return
        END                         ; Mark the end of this file
  • ADRL

功能:在特定范围之内把地址加载到寄存器(并不会执行数据加载),如果在访问范围之内则汇编器会把该伪指令转换为两条数据处理汇编指令来加载地址,否则就报错。
语法格式入下:
ADRL{cond} Rd,label
同样label和ADR必须同属于一个代码段。
相比ADR,ADRL有更宽泛的访问范围,下面是lable相对当前指令距离限制

指令 偏移范围
A32 的ADRL 任何可以通过2个ADD/SUB指令生成的数据
T32 32位的ADRL ±1MB
T32 16位的ADRL 不可用
  • LDR

相对上面两条指令只能在当前代码段范围访问,LDR Rd,=Label伪指令可以跨段访问,至于为什么能跨段,因为汇编器+链接器做了更复杂的处理:)


参考文献
【1】DUI0801I_armasm_user_guide

你可能感兴趣的:(ARM汇编之加载地址到寄存器)