版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012351051/article/details/81394819
ldr的这两种用法总是容易混淆的,先说结论:
ldr r0,label是将标识label处的内容赋值给r0,而ldr r0,=label则是将label这个这个所谓的立即数 数值赋值给r0。
来看几个例子:
_TEXT_BASE:
.word TEXT_BASE
_armboot_start:
.word _start
_bss_start:
.word __bss_start
_bss_end:
.word _end
_start: b reset
ldr pc, _undefined_instruction
ldr pc, _software_interrupt
......
ldr r0, =pWTCON
......
ldr r0, =INTMSK
......
ldr r1, _TEXT_BASE
......
ldr r3, _bss_start
ldr r1, _bss_end
.....
ldr pc, _start_armboot
_start_armboot: .word start_armboot
我们来翻译下前面的各条语句的含义:
ldr pc, _undefined_instruction //将链接地址_undefined_instruction指向的内容赋值给pc,由于PC寄存器是程序执行的指针,其作用相当与指引CPU跳转到这个标志指向的内容进行执行程序。
ldr r0, =pWTCON //这个是立即数,pWTCON是一个宏定义,这里就是进行宏定义展开,所以相当与直接将pWTCON宏定义值(0x15300000)赋值给r0,然后就可以实现对外围硬件的配置了。
ldr r1, _TEXT_BASE //_TEXT_BASE使用.word储存一个字,内容为TEXT_BASE
也就实现了将TEXT_BASE(注意这里没有前缀下划线,它是一个在别的文件中的宏定义)赋值给r1
ldr r0, _bss_start /* find start of bss segment */
ldr r1, _bss_end //道理同上,其实是将分配的bss段的首尾链接地址指向的内容分别赋值给r0和r1
ldr pc, _start_armboot //道理同上,实现程序的跳转,跳转到_start_armboot进行执行。