arm汇编—ldr加载指令,ldr伪指令

分类: 嵌入式

2014-01-17 17:15:20

操作系统:ubuntu10.04
汇编语言:arm

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       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伪指令。

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取出,即多取一次存储器。

参考文件:
1,http://www.cnblogs.com/hnrainll/archive/2011/06/14/2080241.html

原文地址:https://www.cnblogs.com/Linu-Later/p/11657552.html

时间: 2024-10-01 04:13:55

arm汇编—ldr加载指令,ldr伪指令的相关文章

ARM汇编- LDR加载指令,LDR伪指令

1,ldr加载指令LDR指令的格式为:LDR{条件}  目的寄存器,<存储器地址>LDR指令用亍从存储器中将一个32位的字数据传送到目的寄存器中.该指令通常用亍从存储器中读取32位的字数据到通用寄存器,然后对数据迕行处理.当程序计数器PC作为目的寄存器时,指令从存储器中读取的字数据被当作目的地址,从而可以实现程序流程的跳转.该指令在程序设计中比较常用,丏寻址方式灵活多样,请读者认真掌握.指令示例: LDR R0,[R1]                                     

【转】arm汇编—ldr加载指令,ldr伪指令

1,ldr加载指令 LDR指令的格式为:LDR{条件}  目的寄存器,<存储器地址>LDR指令用亍从存储器中将一个32位的字数据传送到目的寄存器中.该指令通常用亍从存储器中读取32位的字数据到通用寄存器,然后对数据迕行处理.当程序计数器PC作为目的寄存器时,指令从存储器中读取的字数据被当作目的地址,从而可以实现程序流程的跳转.该指令在程序设计中比较常用,丏寻址方式灵活多样,请读者认真掌握.指令示例:LDR R0,[R1]         :将存储器地址为R1的字数据读入寄存器R0.LDR R0

ARM中LDR伪指令与LDR加载指令

ARM指令集中,LDR通常都是作加载指令的,但是它也可以作伪指令. LDR伪指令的形式是“LDR Rn,=expr”.下面举一个例子来说明它的用法. COUNT EQU       0x40003100 …… LDR       R1,=COUNT MOV      R0,#0 STR       R0,[R1] COUNT是我们定义的一个变量,地址为0x40003100.这中定义方法在汇编语言中是很常见的,如果使用过单片机的话,应该都熟悉这种用法. LDR       R1,=COUNT是将C

STM LDM汇编批量加载指令的错误用法

一.背景 在调试程序过程中,遇到一个问题,程序入栈出栈后,总是跑飞,用gdb调试,发现入栈操作后,查看入栈后的数据在出栈时不对应. 二.分析内容 1. STMFD   SP!,    {R0-R12, R1} 以前理解是,先入栈R1,然后在依次递减入栈R12--->R0, 理论上 一共入栈14个数据 反编译后,发现竟然少了一个,入栈13个数据 反编译的汇编如下: 23e062fc: e92d1fff push {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, sl

ARM开发板加载Realtek-8188CUS USB无线网卡(一)

平台参数: 内核: Linux 3.6 文件系统:Busybox-1.20.2 硬件参数:S3C2416 在ARM-Linux支持并自动挂载U盘中已经验证好,USB接口是完全正常的,所以不用担心硬件上的故障. 一.引子 BZ使用的是"迅捷"(FAST)的一个USB接口无线网卡,型号FAST FW150US,关于这个网卡的故事... 实物如图: 通过Linux的lsusb命令可以查看它内部使用的是Realtek 8188CUS芯片: 二.正式开场 1.首先在Realtek官网下载对应的驱

Vue 自定义图片懒加载指令v-lazyload

Vue是可以自定义指令的,最近学习过程中遇见了一个需要图片懒加载的功能,最后参考了别人的代码和思路自己重新写了一遍.以下将详细介绍如何实现自定义指令v-lazyload. 先看如何使用这个指令: <img v-lazyload="imageSrc" > imageSrc是要加载的图片的实际路径. 为了实现这个指令,我们首先单独建立一个文件,名字为lazyload.js.并填写基本的代码,如下: //Vue 图片懒加载,导出模块 export default (Vue , o

ARM开发板加载Realtek-8188CUS USB无线网卡(二)

平台参数: 内核: Linux 3.6 文件系统:Busybox-1.20.2 硬件参数:S3C2416 三.工具准备.知识准备 曾经一个山民说过,磨刀不误砍柴工.捣鼓WiFi,,那么WiFi相关的知识总要了解些吧,比如该无线网络的标准.涉及到的名词.加密术语等等,这些在附录里面提及. 现在要说的是,调试无线网卡需要的几个工具. 所有需要的工具都在源码包里,即wireless_tools/wireless_tools.30.rtl.tar.gz.解压之,修改Makefile: ## Compil

7.arm汇编 bic和orr指令

1. bic BIC指令的格式为: BIC{条件}{S}  目的寄存器,操作数1,操作数2 BIC指令用于清除操作数1的某些位,并把结果放置到目的寄存器中. 操作数1应是一个寄存器, 操作数2可以是一个寄存器.被移位的寄存器.或一个立即数. 操作数2为32位的掩码,如果在 掩码中置了某一位1,则清除这一位.未设置的掩码位保持不变. bic r0,r0,#0x1f 0x1f=11111b 其含义:清除r0的bit[4:0]位. 2. orr ORR指令的格式为: ORR{条件}{S}  目的寄存器

ARM汇编指令的一些总结-转

ARM汇编指令的一些总结ARM汇编指令很多,但是真正常用的不是很多,而且需要认真琢磨的又更少了.比较有用的是MOV B BL LDR STR还是通过具体汇编代码来学习吧.@ disable watch dog timer mov r1, #0x53000000 //立即数寻址方式mov r2, #0x0str r2, [r1] MOV 没有什么好说的,只要掌握几个寻址方式就可以了,而且ARM的寻址方式比386的简单很多.立即数寻址方式,立即数要求以“#”作前缀,对于十六进制的 数,还要求在#后面