转载:https://my.oschina.net/zengsai/blog/23733

ARM LDR 伪指令的格式:

LDR     Rn, =expr

如果name是立即数的话
LDR R0,=0X123;//将0X123存入R0
如果name时个标识符
LDR R0,=NAME;//将NAME的地址存入R0

LDR    R0, =0x3FF5000  ; 伪指令: 把 0x3FF5000 直接赋值给 R0,相当于 R0=0x3FF5000。
LDR R0, 0x3FF5000 ; 存储访问指令: 把以 0x3FF5000 为地址的存储单元中的数据赋值给 R0, 相当于 R0=[0x3FF5000]。

附1 《ARM中LDR伪指令与LDR加载指令》:

ARM指令集中,LDR通常都是作加载指令的,但是它也可以作伪指令。

ARM是RISC结构,数据从内存到CPU之间的移动只能通过L/S指令来完成,也就是ldr/str指令。

比如想把数据从内存中某处读取到寄存器中,只能使用ldr 加载指令
比如:
ldr r0, 0x12345678 
就是把0x12345678这个地址中的值存放到r0中。

而mov不能干这个活,mov只能在寄存器之间移动数据,或者把立即数移动到寄存器中,这个和x86这种CISC架构的芯片区别最大的地方。
x86中没有ldr这种指令,因为x86的mov指令可以将数据从内存中移动到寄存器中。

虽然ldr伪指令和ARM的ldr指令很像,但是作用不太一样。ldr伪指令可以在立即数前加上=,以表示把一个地址写到某寄存器中,比如:
ldr r0, =0x12345678

这样,就把0x12345678这个地址写到r0中了。所以,ldr伪指令和mov是比较相似的。只不过mov指令限制了立即数的长度为8位,也就是不能超过512。而ldr伪指令没有这个限制。如果使用ldr伪指令时,后面跟的立即数没有超过8位,那么在实际汇编的时候该ldr伪指令是被转换为 mov指令的。

ldr伪指令和ldr指令不是一个同东西。


附2 《ARM 伪指令之地址读取 》

1、ADR伪指令--- 小范围的地址读取

ADR伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中。在汇编编译器编译源程序时,ADR伪指令被编译器替换成一条合适的指令。通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能用一条指令实现,则产生错误,编译失败。

ADR伪指令格式 :ADR{cond}   register, expr

地址表达式expr的取值范围:

当地址值是字节对齐时,其取指范围为: +255  ~ 255B;

当地址值是字对齐时,其取指范围为:   -1020 ~ 1020B;

2、ADRL伪指令----中等范围的地址读取

ADRL伪指令将基于PC相对偏移的地址值或基于寄存器相对偏移的地址值读取到寄存器中,比ADR伪指令可以读取更大范围的地址。在汇编编译器编译源程序时,ADRL伪指令被编译器替换成两条合适的指令。若不能用两条指令实现,则产生错误,编译失败。

ADRL伪指令格式:ADRL{cond}   register, expr

地址表达式expr的取值范围:

当地址值是字节对齐时,其取指范围为: -64K~64K;

当地址值是字对齐时,其取指范围为:   -256K~256K;

3、LDR伪指令-----大范围的地址读取

LDR伪指令用于加载32位的立即数或一个地址值到指定寄存器。在汇编编译源程序时,LDR伪指令被编译器替换成一条合适的指令。若加载的常数未超出MOV或MVN的范围,则使用MOV或MVN指令代替该LDR伪指令,否则汇编器将常量放入文字池,并使用一条程序相对偏移的LDR指令从文字池读出常量。

转载:https://www.cnblogs.com/hnrainll/archive/2011/06/14/2080241.html

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

汇编--LDR的更多相关文章

  1. bootloader的移植

    jz2440开发板 在介绍bootloader里边的内容的时候,需要知道的是: bootloader的引入的目的就是启动linux内核,一个简单的bootloader编写需要以下的步骤: ①初始化硬件 ...

  2. 汇编指令-adr与ldr伪汇编区别(8)

    adr :相对寻址,与当前位置有关 ldr  :绝对寻址,与当前位置无关 在初始化SDRAM时就会用到adr,代码如下: /* 初始化SDRAM */ ldr r0,=BWSCON //r0=SDRA ...

  3. ARM 汇编指令 ADR 与 LDR 使用

    简介 这两个都是伪指令:ADR 是小范围的地址读取伪指令,LDR 是大范围的读取地址伪指令.可实际使用的区别是: ADR 是将基于 PC 相对偏移的地址值或基于寄存器相对地址值读取的伪指令,而 LDR ...

  4. ARM汇编中ldr伪指令和ldr指令(转载)

    转自:http://blog.csdn.net/ce123_zhouwei/article/details/7182756 ARM是RISC结构,数据从内存到CPU之间的移动只能通过L/S指令来完成, ...

  5. arm汇编:ldr,str,ldm,stm,伪指令ldr

    ldr,str,ldm,stm的命名规律: 这几个指令命名看起来不易记住,现在找找规律. 指令 样本 效果 归纳名称解释 ldr Rd,addressing ldr r1,[r0] addressin ...

  6. 汇编指令-MOV与ldr区别(7)

    MOV 1.可以寄存器与寄存器之间传递数据 2.可以常数传递到寄存器中(常数不能超过32位) LDR 1.可以地址与寄存器之间的数据传递 2.也可以常数传递到寄存器中 实例: 1.r1与r2之间传递就 ...

  7. 汇编指令-位置无关码(BL)与绝对位置码(LDR)(2)

    位置无关码,即该段代码无论放在内存的哪个地址,都能正确运行.究其原因,是因为代码里没有使用绝对地址,都是相对地址.  位置相关码,即它的地址与代码处于的位置相关,是绝对地址 BL :带链接分支跳转指令 ...

  8. 汇编指令:ldr和str,ldm和stm的区别

    (1)LDR:L表示LOAD,LOAD的含义应该理解为:Load from memory into register.下面这条语句就说明的很清楚: LDR   R1,     [R2] R1<— ...

  9. arm汇编指令--str ldr

    STR :把寄存器中的字保存到存储器(寄存器到存储器) 示例: STR R0,[R1],#8             :将R0中的字数据写入以R1为地址的存储器中,并将新地址R1+8写入R1.STR ...

随机推荐

  1. C++病毒

    病毒代码一#include <bits/stdc++.h> #include <windows.h> using namespace std; void HideWindow( ...

  2. Stage 1 项目需求分析报告

    迷你商城后台管理系统-- 需求分析 1. 引言 作为互联网热潮的崛起,消费者们的普遍差异化,实体商城要想在互联网的浪潮中继续发展,就需要制定出针对用户以及消费者的消费习惯以及喜爱品种的消费方案.从而企 ...

  3. PHP中使用if的时候为什么建议将常量放在前面?

    在某些框架或者高手写的代码中,我们会发现有不少人喜欢在进行条件判断的时候将常量写在前面,比如: if(1 == $a){ echo 111; } 这样做有什么好处呢?我们假设一个不小心的粗心大意,少写 ...

  4. 『GoLang』语法基础

    标识符 字母或下划线开头 之后只能出现数字.字母.下划线 大小写敏感 Go语言关键字 break default func interface select case defer go map str ...

  5. 鸿蒙内核源码分析(重定位篇) | 与国际接轨的对外部发言人 | 百篇博客分析OpenHarmony源码 | v55.01

    百篇博客系列篇.本篇为: v55.xx 鸿蒙内核源码分析(重定位篇) | 与国际接轨的对外部发言人 | 51.c.h.o 加载运行相关篇为: v51.xx 鸿蒙内核源码分析(ELF格式篇) | 应用程 ...

  6. Python中open和with open有什么区别?怎么用?

    open 打开文件 file=open("文件名","读写模式") 操作文件 代码段 关闭文件 file.close() 注意事项:使用open方法,文件操作完 ...

  7. NOIP 模拟一 考试总结

    序列 考场上信心满满的打了nlogn的做法,我以为我稳了.据考试结束1h时发现看错题目了,打成了不连续的子序列.匆匆改了n2logn的做法.考试结束后,我发现我跪了.原来到终点才会发现我做的和人家不是 ...

  8. 记一次 .NET 某电商定向爬虫 内存碎片化分析

    一:背景 1. 讲故事 上个月有位朋友wx找到我,说他的程序存在内存泄漏问题,寻求如何解决? 如下图所示: 从截图中可以看出,这位朋友对 windbg 的操作还是有些熟悉的,可能缺乏一定的实操经验,所 ...

  9. 阿里 Midway 正式发布 Serverless v1.0,研发提效 50%

    Github:https://github.com/midwayjs/midway 开源为了前端和 Node.js 的发展,点 Star! 去年阿里提出 Serverless 架构,并利用其新一代研发 ...

  10. 给力!斩获 GitHub 14000 Star,两周创办开源公司获数百万美元融资

    文章来源|AI科技大本营 作者|伍杏玲 上世纪 90 年代初,21 岁大学生 Linus Torvalds 开源 Linux 操作系统,自此掀起全球开源浪潮.随后"中国 Linux 第一人& ...