ARM 中 LDR伪指令

发布者:电子创意达人最新更新时间:2024-09-06 来源: cnblogs关键字:ARM  LDR伪指令 手机看文章 扫描二维码
随时随地手机看文章

我们知道ARM CPU中有一条被广泛使用的指令LDR,它主要是用来从存储器(确切地说是地址空间)中装载数据到通用寄存器。但不论是ARMASM还是GNU ARM AS,都提供了一条与之同名的伪指令LDR,而在实际中使用该伪指令的情况也较多,那他们有什么不同呢?下面我谈谈我的理解。


由于我使用GNU工具链,所以以下的内容都以GNU AS的ARM语法为准。


LDR伪指令的语法形式如下:

LDR , =


这个常量表达式中可以包含Label(在ARM汇编中Label会在连接时解释为一个常数),且其中的常数前不加#符号。


1 .equ    STACK_BASE, 0x0c002000

2 .equ    STACK_SIZE, 0x00001000

4 .text

5     ldr    sp, = STACK_BASE

6     ldr    sl, = STACK_BASE - STACK_SIZE

7     ldr    pc, = entry


这是一个合法的汇编文件,它把堆栈基址设为0x0c002000,栈限设为0x0c001000,然后跳到entry所标识的C程序中执行。


下面我们假设符号“entry”的地址为0x0c000000。


我们如果把上面代码写成:


1 .text

2     mov    sp, #0x0c002000

3     mov    sl, #0x0c001000

4     mov    pc, #0x0c000000

 

汇编器会报错:

demo.s: Assembler messages:

demo.s:2: Error: invalid constant -- `mov sp,#0x0c002000'

demo.s:3: Error: invalid constant -- `mov sl,#0x0c001000'


说起这个错误的原因可就话长了,简而言之是因为RISC有一个重要的概念就是所有指令等长。在ARM指令集中,所有指令长度为4字节(Thumb指令是2 字节)。那问题就来了,4字节是不可能同时存的下指令控制码和32位立即数的,那么我要把一个32位立即数(比如一个32位地址值)传送给寄存器该怎么 办?


RISC CPU提供一个通用的方法就是把地址值作为数据而不是代码,从存储器中相应的位置读入到寄存器中,待会我们会看到这样的例子。


此外ARM还提供另一种方案。由于传送类指令的指令控制码部分(cond, opcode, S, Rd, Rn域)占去了20个字节,那能提供给立即数的就只剩12个位了。


ARM并未使用这12个位来直接存一个12位立即数,而是使用了类似有效数字一样的概念,只存8个字节的有效位和一个4位的位偏移量(偏移单位为2)。这个东西在ARM被叫做术语immed_8,有兴趣的人可以找资料了解一下,到处都有介绍。


可以看出ARM的这个方法能直接使用的立即数是相当有限的,像0xfffffff0这样的数显然无法支持。别着急,ARM的传送类指令中还有一个MVN指 令可以解决该问题。显然0x0000000f是一个有效立即数,MVN会先将其取反再传送,这样有效立即数的范围又扩充了一倍。


可就算如此仍有大量的32位立即数是无效的,比如上面那个例子中的0x0c002000和0x0c001000。面对这种问题一是使用RISC的通用方法,二是分次载入。


比如可以这样载入0x0c002000:


1 .text

2     mov    sp, #0x0c000000

3     add    sp, sp, #0x00002000

 


或者:


.text

    mov    sp, #0x0c000000

    orr    sp, sp, #0x00002000

 


感觉很狡猾是吧,呵呵。但是要注意它和方法一的一大区别:需要多条指令。那么在一些对指令数目有限制的场合就无法使用它,比如异常向量表处要做长跳转(超过±32MB)的话就只能用方法一;还有就是在同步事务中该操作不是原子的,因此可能需要加锁。


扯了这么多再回到LDR伪指令上来。显然上面的内容是复杂繁琐的,如果然程序员在写程序的时候还要考虑某个数是不是immed_8一定超级麻烦,因此为了减轻程序员的负担才引入了LDR伪指令。


你一定很好奇第一段代码demo.s被GNU AS变成了什么,好,让我们在Linux环境下执行下面的命令:

        arm-elf-as -o demo.o demo.s

        arm-elf-objdump -D demo.o


结果:


demo.o:     file format elf32-littlearm


Disassembly of section .text:


00000000 <.text>:

   0:   e59fd004        ldr     sp, [pc, #4]    ; c <.text+0xc>

   4:   e59fa004        ldr     sl, [pc, #4]    ; 10 <.text+0x10>

   8:   e59ff004        ldr     pc, [pc, #4]    ; 14 <.text+0x14>

   c:   0c002000        stceq   0, cr2, [r0]

  10:   0c001000        stceq   0, cr1, [r0]

  14:   00000000        andeq   r0, r0, r0

Disassembly of section .data:


由于entry还没连上目标地址,objdump反汇编会认为是0,我们先不管它。另外两条LDR伪指令变成了实际的LDR指令!但目标很奇怪,都是[pc, #4]。那好我们看看[pc, #4]是什么。



我们知道pc中存放的是当前指令的下下条指令的位置,也就是. + 8。那么上面的第一条指令ldr sp, [pc, #4]中的pc就是0x8,pc + 4就是0xc,而[0xc]的内容正是0x0c002000;同理,第二条ldr指令也是如此。显然这里LDR伪指令采用的是RISC通用的方法。


另外要说的是,如果LDR的是一个immed_8或者immed_8的反码数,则会直接被解释成mov或mvn指令。如ldr pc, = 0x0c000000会被解释成mov pc, 0x0c000000。


最后一点补充,我发现arm-elf-gcc通常都用累加法。如C语句中的i = 0x100ffc04;会变成类似于以下的语句:

       mov   r0, #0x10000004

       add   r0, r0, #0x000ff000

       add   r0, r0, #0x00000c00

       ...

原因不详。


关键字:ARM  LDR伪指令 引用地址:ARM 中 LDR伪指令

上一篇:在嵌入式Linux系统(OK6410)中移植Boa 服务器
下一篇:OK6410 rmmod卸载模块失败:No such file or directory

推荐阅读最新更新时间:2024-11-09 11:09

arm: 使用结构体操作寄存器
使用结构体操作寄存器: //寄存器赋值和取值的时候,要注意寄存器的长度,有的寄存器的值只有8位。 //还要注意,使用volatile修饰寄存器变量。volatile 参考http://www.cnblogs.com/mylinux/p/4630749.html //addr.h typedef unsigned int S3C24X0_REG32; /* NAND FLASH (see S3C2410 manual chapter 6) */ typedef struct { S3C24X0_REG32 NFCONF; S3C24X0_REG32 NFCMD; S3C24X0_REG32 NFADDR;
[单片机]
arm-linux-gcc .s 和 .S 的区别 !
unix/linux 对 大小写敏感: .s 操作 :汇编 .S 操作 : cpp + 汇编 eg: /* start.s */ #define rTEXT 0x12345678 LDR R0,=rTEXT .... # arm-linux-gcc -g -c -nostdlib start.s -o start.o # nm -u start.o rTEXT # arm-linux-objdump -S -t start.o start.l # cat start.i | grep ''R0 LDR R0,【PC,#0】 经典错误: arm-linux-gcc 将.s 文件误认为cpp处理后
[单片机]
imec 牵头组建汽车芯粒计划,Arm、宝马集团、博世等巨头首批承诺加入
10 月 21 日消息,据 imec 微电子研究中心比利时当地时间本月 10 日公告,包括 Arm、宝马集团、博世在内的多家重要企业承诺首批加入 imec 牵头组建的汽车芯粒 / 小芯片计划(Automotive Chiplet Program,简称 ACP)。 其余宣布率先加入 ACP 计划的企业还包括: 日月光(外包封测 OSAT 巨头)、Cadence 楷登电子、西门子、SiliconAuto(鸿海科技与 Stellantis 合资车用芯片设计企业)、Synopsys 新思科技、Tenstorrent、法雷奥(汽车零部件供应巨头)。 imec 表示,传统的车用芯片方案在满足 ADAS、车载娱乐系统等越来越复杂的需求上日益
[汽车电子]
Part3_lesson1---ARM汇编编程概述
bootloader以及内核需要使用汇编语言,特别是在初始化的时候!以及在效率要求很高的地方会使用。 汇编程序框架: 其入口在_start处,这个入口需要用一个关键字为.global来声明它是一个全局的标号,那么在外部文件才能够引用到它。 .section表示这是一个段,.text表示这是一个代码段。 简化之后的框架 要调试某个文件是把格式为elf的文件烧写到内存里面去调试。 要下载某个文件是要把格式为二进制的文件烧写到nandflash里面去运行。 start.S文件 makefile文件的编写: all:start.o   arm-linux-ld -Ttext 0x50000000 -o start.elf
[单片机]
Part3_lesson1---<font color='red'>ARM</font>汇编编程概述
谷歌 Pixel Watch 细节解密:与 NXP 开发 Arm M33 协处理器
IT之家 5 月 25 日消息,谷歌在其 I / O 大会上公布了一款全新的智能手表 ——Pixel Watch,圆润而又精致的外观引起很多人的喜爱。但很可惜,谷歌没有透露 Pixel Watch 的具体规格,预计谷歌将会在 10 月份举行新品上市发布会。 但现在关于 Pixel Watch 的细节爆料也逐渐增多,例如 RAM、设备协处理器等等,让我们对这款设备有了更好的了解。 现在,@Max Winebach 确认了更多有关细节,其协处理器被命名为Arm M33,功耗极低(以微瓦为单位)。此外,这款手表将搭载三星 Exynos 9110 处理器,配备 1.5 GB 的 RAM 和 32 GB 的 ROM 存储,带来流畅的
[手机便携]
谷歌 Pixel Watch 细节解密:与 NXP 开发 <font color='red'>Arm</font> M33 协处理器
ARM32 ARM64 的设备树匹配及兼容ATAGS
arm32 arm64 u-boot 加载 linux的命令 bootm bootm uImage_addr // 无设备树,bootm 0x30007FC0 bootm uImage_addr initrd_addr dtb_addr // 有设备树 --- nand read.jffs2 0x30007FC0 kernel; // 读内核uImage到内存0x30007FC0 nand read.jffs2 32000000 device_tree; // 读dtb到内存32000000 bootm 0x30007FC0 - 0x32000000 // 启动, 没有
[单片机]
如何在STM32F4 ARM MCU和Python之间建立USART通信
步骤1:软件和硬件要求 在硬件方面,您需要: STM32F4发现板(或其他任何STM32板) USB转TTL转换器 在软件方面: STM32CubeMX Keil uVision5 已安装串行库的Python 步骤2:STM32CubeMX配置 首先让我们了解我们想要做什么。我们希望通过USART从Python将数据传输到板上,并检查是否有正确的数据并切换LED。因此,我们需要启用USART和Led。 从“连接性”选项卡中启用USART2。 将模式更改为异步 波特率更改为9600 Bits/s 无奇偶校验的字长为8位 无奇偶校验位 从DMA设置中以特殊模式添加USART2_RX 从NVIC设置中启用USART2全局中断 然后生
[单片机]
欧盟推出首台ExaFlop超级计算机 采用ARM与NVIDIA的架构
官方消息,欧盟的首台 ExaFLOP 超级计算机将分别采用 ARM 和英伟达的架构,这标志着该地区在人工智能发展方面取得了突破性进展。欧盟开发首台 ExaFLOP 超级计算机表明其致力于实现完全的 技术独立 。 超级计算机 Jupiter 的总预算为 2.73 亿欧元。开发工作由欧洲高性能计算联合企业(European High-Performance Computing Joint Undertaking)以及由 Eviden 和 ParTec 组成的科技公司集团负责。ARM 超级计算机在业界的存在感一直很低,前十大超级计算机中只有一台采用了该架构。Jupiter 超级计算机将加入这一行列,因为据说它将采用 SiPearl 的
[网络通信]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

更多每日新闻

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved