ARM指令集中,LDR通常都是作加载指令的,但是它也可以作伪指令。 LDR伪指令的形式是“LDR Rn,=expr”。下面举一个例子来说明它的用法。 COUNT EQU 0x40003100 …… LDR R1,=COUNT MOV R0,#0 STR R0,[R1] COUNT是我们定义的一个变量,地址为0x40003100。这中定义方法在汇编语言中是很常见的,如果使用过单片机的话,应该都熟悉这种用法。 LDR R1,=COUNT是将COUNT这个变量的地址,也就是0x40003100放到R1中。 MOV R0,#0是将立即数0放到R0中。最后一句STR R0,[R1]是一个典型的存储指令,将R0中的值放到以R1中的值为地址的存储单元去。实际就是将0放到地址为0x40003100的存储单元中去。可 见这三条指令是为了完成对变量COUNT赋值。用三条指令来完成对一个变量的赋值,看起来有点不太舒服。这可能跟ARM的采用RISC有关。 下面还有一个例子 ;将COUNT的值赋给R0 LDR R1,=COUNT LDR R0,[R1] LDR R1,=COUNT这条伪指令,是怎样完成将COUNT的地址赋给R1,有兴趣的可以看它编译后的结果。这条指令实际上会编译成一条LDR指令和一条DCD伪指令。 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取出,即多取一次存储器。
这篇文章针对用法1进行了详细的说明说说ARM汇编的LDR伪指令 |
|
来自: BeautymengRoom > 《我的图书馆》