3.9.7. 汇编中设置某个寄存器的值或给某个地址赋值

在汇编代码start.S中,看到不止一处, 类似于这样的代码:

形式1:

# define pWTCON		0x53000000
......
	ldr     r0, =pWTCON
	mov     r1, #0x0
	str     r1, [r0]
        

或者是,

形式2:

# define INTSUBMSK	0x4A00001C
......
	ldr	r1, =0x7fff
	ldr	r0, =INTSUBMSK
	str	r1, [r0]
        

其含义,都是将某个值,赋给某个地址,此处的地址,是用宏定义来定义的,对应着某个寄存器的地址。

其中,形式1是直接通过mov指令来将0这个值赋给r1寄存器,和形式2中的通过ldr伪指令来将0x3ff赋给r1寄存器,两者区别是,前者是因为已经确定所要赋的值0x0是mov的有效操作数,而后者对于0x3ff不确定是否是mov的有效操作数

[警告]警告

如果不是,则该指令无效,编译的时候,也无法通过编译,会出现类似于这样的错误::

    start.S: Assembler messages:
    start.S:149: Error: invalid constant -- 'mov r1,#0xFFEFDFFF'
    make[1]: *** [start.o] 错误 1
    make: *** [cpu/arm920t/start.o] 错误 2
            

所以才用ldr伪指令,让编译器来帮你自动判断:

  1. 如果该操作数是mov的有效操作数,那么ldr伪指令就会被翻译成对应的mov指令

    例 3.2. 

    举例说明:

    汇编代码:

    # define pWTCON		0x53000000
    ......
    	ldr     r0, =pWTCON
                        

    被翻译后的真正的汇编代码:

    33d00068:	e3a00453 	mov	r0, #1392508928	; 0x53000000
                        


  2. 如果该操作数不是mov的有效操作数,那么ldr伪指令就会被翻译成ldr指令

    例 3.3. 

    举例说明:

    汇编代码:

    	ldr	r1, =0x7fff
                        

    被翻译后的真正的汇编代码:

    33d00080:	e59f13f8 	ldr	r1, [pc, #1016]	; 33d00480 <fiq+0x60>
    ......
    33d00480:	00007fff 	.word	0x00007fff
                        

    即把ldr伪指令翻译成真正的ldr指令,并且另外分配了一个word的地址空间用于存放该数值,然后用ldr指令将对应地址中的值载入,赋值给r1寄存器。



[注意]总结汇编中给某个地址赋值的方法

汇编中,一个常用的,用来给某个地址赋值的方法,类似如下形式:

#define 宏的名字  寄存器地址
......
	ldr	r1, =要赋的值
	ldr	r0, =宏的名字
	str	r1, [r0]