ARM编程进阶之一 —— ARM汇编伪指令

发布者:幸福自由最新更新时间:2023-05-06 来源: elecfans关键字:ARM  编程进阶  汇编伪指令 手机看文章 扫描二维码
随时随地手机看文章

到目前为止,我们已经具备编写较为复杂的ARM汇编程序的能力,但要编写较为复杂且实用的程序,我们就不得不掌握ARM汇编的伪指令(pseudo-instruction)。千万别把汇编伪操作(directive)与汇编伪指令(pseudo-instruction)弄混了,directive不会被编译器编译为机器指令,但pseudo-instruction会。而pseudo-instruction与指令(instruction)的区别在于,1条instruction与1条机器指令对应,而编译器会把1条pseudo-instruction编译为1条或多条机器指令。

ARM汇编伪指令共4条:ldr、adr、adrl、nop

1、ldr

首先我们来回答“基本寻址模式与基本指令”一文中提出的问题。“如果我们需要mov r0, #10000这样的指令,应该怎么办?(常数10000不能在机器指令32bit中的低12bit中被表示出来)”。当你进行编译的时候,“Error:All70E”的错误就会出现,如下图。

image

其实,这个问题很容易解决,只需要将mov r0, #10000换为ldr r0, =10000即可。为什么这样就可以了呢?因为,这里的ldr r0, =10000并非我们已经学过的ldr指令,而是一条伪指令,编译器会将这条伪指令替换为:

ldr r0, [pc, #-4]
DCD 10000

DCD所分配的内存空间中存放了整数10000,该内存空间被称为literal pool,中文名称“文字池”。由于整个程序都是由编译器编译的(包括文字池的分配),所以很显然编译器能够知道ldr指令在内存中的地址与文字池在内存中的位置之间的偏移量,因此编译器就可以正确地使用以pc为基址,采用相对寻址的ldr指令将文字池中的数取出加载到寄存器r0中。由此可见,编译器对于ldr r0, =10000这条伪指令的处理,其实质是:

在汇编源程序时,LDR伪指令被编译器替换成一条合适的指令和存放常数的文字池。汇编器将常量放入文字池,并使用一条程序相对偏移的LDR指令从文字池读出常量。 

由于,4byte可以存放任何int型整数,这样一来,常数就可以是任何int型整数,而不再受制于12bit的限制。当然此时的常数是存放在内存中的,而不是存放在机器指令的32bit编码中的。

额外说明:

a)、ldr r0, [pc, #-4]中是-4,而不是+4,是由于流水线的原因(参见“流水线对PC值的影响”一文)。今后对于流水线的这种影响,我将不再予以特别说明。

b)、从指令位置到文字池的偏移量必须小于4KB

c)、从语法上来看,与ARM指令的LDR相比,伪指令LDR的参数有“=”号,没有“#”号

d)、如果常数能够被12bit表示出来,例如:ldr r0, =0×100,那么,编译器对该伪指令的处理,是使用MOV(或者MVN)指令代替该LDR伪指令,例如:mov r0, #0×100,而不会采用ldr指令+文字池的方式。

除了 ldr 寄存器, =常数 这种形式外,还有ldr 寄存器, =标号 这种形式也经常被使用,下面我就来讲解这种形式的ldr伪指令。

image

由上图可见:ldr pc, =InitStack这条伪指令的作用是将标号InitStack所代表的地址赋予pc。 这里会使我们产生几个疑问:

a)、为什么不使用bl InitStack,而要使用ldr pc, =InitStack?

这是因为bl指令的跳转范围是正负32M,而InitStack所代表的位置有可能距离ldr pc, =InitStack超过32M,此时bl就无能为力了。竟然存在这么大范围跳转的程序(这似乎意味着编译出来的二进制可执行文件的大小会操作32M),这一点似乎令我们感到非常震惊。事实上是:大小超过32M的可执行程序的确几乎不可能出现,但即使是很小的二进制程序中也可能进行大范围(超过32M)的跳转,这一点在bootloader程序中几乎是必然的。

b)、编译器是如何得出InitStack所代表的地址是0×64?

编译器知道MOV R0, LR这条指令相对于整个程序的第1条指令的偏移量为0×64;同时又知道这个程序将来在内存中的运行地址为0×0,所以编译器在编译的时候(不是程序运行的时候)就可以确定InitStack所代表的地址为0×64+0×0=0×64。那么编译器又是如何知道“程序将来在内存中的运行地址”的呢?其实,这个“程序将来在内存中的运行地址”,我通常称它为“程序的期望运行地址”,简称“运行地址”,以后我也将这样称呼它。它其实是在编译程序前由程序员告知编译器的。

未标题-1

c)、如果将来程序并没有运行在它的运行地址处,很显然这个程序就会出问题。如何解决?

出问题的原因,显然是由于ldr伪指令使用的绝对地址。所以,解决的办法就是使用相对地址,进行相对寻址。这就要用到我们下面要介绍的另一条伪指令adr

2、adr

ADR伪指令的作用与LDR伪指令的作用相同,都是将标号所代表的地址赋予寄存器,不过2者的实现机制是完全不同的:ldr采用绝对地址,adr采用相对地址。

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

image

很显然,由于将ADR R0, Delay替换为ADD r0, pc, #0x3c,而它是以当前指令的地址(pc的值)进行相对地址计算的。所以即使将来程序没有实际运行在运行地址处,也不会有问题。

当然,这里还有2个问题:

a)、既然adr和ldr完成类似的功能,adr又能避免绝对地址的问题,还要ldr伪指令有何用?

这主要是因为,adr伪指令要求标号与adr伪指令必须在同一个段中(段的概念参见“ARM汇编伪操作”一文),而ldr伪指令则没有这样的要求。

b)、add r0, pc, #0x3c中的常数0x3c是放在机器指令12bit中的立即数,这个立即数有可能不能被12bit表示出来。此时编译会产生错误。如果出现这样的情况,又应该如何办?

使用下面要讲的伪指令adrl

3、adrl

在汇编源程序时,ADRL伪指令被编译器替换成两条合适的指令。其本质是:将偏移量这个立即数(可能不能被12bit表示出来)拆分为2个可以被12bit表示的立即数,然后用2条add(或sub)指令来替换adrl伪指令。

image

当然你会问,如果那个立即数非常特殊,无论如何也拆分不成2个可以被12bit表示的立即数(也就是说需要拆分为3个甚至更多的数),那又应该如何办?关于这个问题,我在这里不予回答,不过你要记住一句话,如果机器智能到啥都能做的话,你作为程序员就失业了!哈哈!

4、nop

NOP是no operation的意思,就是CPU不做任何事的意思。这里千万要明白,CPU一旦上电就将永不停歇地运行,绝不可能有一条指令能另CPU什么都不做。所以,该伪指令在汇编时将会被代替成“MOV R0,R0”指令。

NOP主要用于短延时操作,关于这一点,这里我要多说几句。与应用程序不同,汇编程序通常要用于控制硬件,例如,你需要使用汇编程序要求某个硬件执行某个操作(例如:初始化nandflash),并要在该操作完成后才能进行后面的操作,而硬件从接到命令到完成该操作需要一段时间(该时间很短,但对CPU而言却较长,通常需要几个指令周期)。此时,程序员就必须在发出命令的指令和后续操作之间做延时,通常的做法就是加入几个NOP伪操作。

附:ldr指令与ldr伪指令的4种形式(这4种形式,极其容易让初学者困惑,所以在此集中列出)

ldr r0, [r1]指令,将内存存放的内容加载到r0中
ldr r0, label指令,将标号label所代表的内存地址处存放的内容加载到r0中
ldr r0, =10000伪指令,将常数10000赋予r0(采用ldr指令+文字池的方式实现)
ldr r0, =lable伪指令,将标号label所代表的内存地址赋予r0


关键字:ARM  编程进阶  汇编伪指令 引用地址:ARM编程进阶之一 —— ARM汇编伪指令

上一篇:S3C2410看门狗驱动分析
下一篇:linux2.6.18内核S3C2410平台移植笔记

推荐阅读最新更新时间:2024-11-07 08:26

基于ARM的浆果采摘机械手运动控制研究
随着计算机和自动控制技术的迅速发展,农业机械将进入高度自动化和智能化时期。浆果采摘机器人的应用可以提高劳动生产率和产品质量,改善劳动条件,解决劳动力不足等问题。浆果采摘机器人主要由机械手及末端执行器、视觉及决策系统、控制系统等部分组成。本文将阐述如何利用ARM 微处理器实现浆果采摘机器手的运动控制。 本控制系统采用ARM(Advanced RISC Machine)微处理器,其与单片机和DSP 等相比具有很强的通用性,以其高速度、高性价比和低功耗等优点被广泛应用于各个领域。 1 控制系统功能要求 浆果采摘机器人的主要执行部分 机械手分为手臂和手腕两部分。机械手如何躲避障碍物并能准确到达果实目标的位置是由机械手的自由度决定的,
[单片机]
基于<font color='red'>ARM</font>的浆果采摘机械手运动控制研究
分析称苹果暂不使用ARM芯片
  美国市场研究公司Real World Technologies分析师大卫·坎特(David Kanter)周二撰文指出,尽管关于苹果在其MacBook Air和 MacBook Pro产品上使用ARM架构的流言漫天飞舞,但是就目前看来,苹果还会使用英特尔的处理器。   以下是文章内容:   此前有媒体报道称苹果在未来两年内将抛弃x86架构,转而使用ARM芯片。这对于正处在与Intel白热化竞争中的ARM来说,是一次巨大胜利。   苹果在其Mac笔记本使用ARM主要出于四方面考虑:第一,统一软件生态环境,最终将iOS与OS X融合。第二,严格控制硬件并且提高硬件集成度。理论上,苹果可以通过这种途径与ARM共同设计包括硬件和软
[手机便携]
Socionext宣布与Arm和台积电合作开发2nm多核CPU芯片
SoC设计与应用技术领导厂商Socionext Inc.(以下“Socionext”)宣布,与Arm和台积电共同合作开发一款低功耗32核CPU ,该芯片基于Chiplet技术,采用台积电2nm制程工艺,能为超大规模数据中心服务器、5/6G基础设施、DPU以及边缘网络市场提供最大性能和最高效率。工程样品预计于2025年上半年发布。 这款基于Chiplet技术的CPU采用Arm® Neoverse™ 计算子系统(CSS)技术,可在单个封装内进行单个或多个实例化、并配备有IO和特定的定制芯片组,为多个目标应用提供灵活的解决方案。当新的芯片组可用时,可以支持经济有效的封装级升级路径。 Socionext执行副总裁兼全球发展部部长
[半导体设计/制造]
中芯、ARM携手90纳米LL/G处理工艺,共谋SoC前沿设计
中芯国际集成电路制造有限公司和ARM公司共同宣布:中芯国际采用ARM Artisan物理IP系列产品中的ARM Metro低功耗/高密度产品和Advantage高性能产品,用于90纳米LL(低渗漏)和G(主流)处理工艺。该协议通过在ARM网站免费下载的方式进一步增进了两家公司在推动前沿设计和制造方案方面的协作和承诺。 中芯国际设计服务副总裁Paul Ouyang表示:“同ARM的继续合作进一步加强了我们对客户的承诺:提供包括ARM高质量的、经芯片验证的物理IP在内的全面的制造发展蓝图。通过和ARM的合作,我们可以向90纳米工艺的客户提供ARM Metro和Advantage产品,帮助他们缩短设计时间、降低风险并加快产品上市速度。
[焦点新闻]
恩智浦展示功能性Cortex-M0硅芯片
恩智浦半导体(NXP Semiconductors)宣布推出世界首款功能性ARM Cortex-M0硅芯片。Cortex-M0处理器在小尺寸、低功耗和高能效方面取得重大突破,其简约的特性使之成为当今市场上最方便易用的架构之一。作为第一家Cortex-M0处理器授权合作方,恩智浦将于3月30日-4月2日在硅谷嵌入式系统大会第1010展台展示功能完善的Cortex-M0硅芯片,重点展示Cortex-M0处理器的能效表现以及在代码密度方面的重大改进。 恩智浦目前正与其主要客户一起合作,计划于2010年初在市场上广泛推出基于Cortex-M0处理器的LPC1100系列产品,目标市场包括电池供电的产品应用、电子计量、消费电子外围设备、远程
[单片机]
ARM CEO:ARM应独立运作,不建议收购
网易科技讯 6月18日消息,据国外媒体报道,ARM控股公司的首席执行官沃伦·伊斯特(Warren East)近日表示,最适合ARM发展的道路就是让其作为一个独立的企业存在,任何企图收购ARM的买家都无疑是在浪费钞票。 伊斯特在旧金山接受采访时表示:“收购ARM的计划没有任何经济意义,那些想收购ARM的人唯一的借口可能就是想把ARM从他的竞争对手名单中除名。” 如今ARM生产的芯片已经被广泛的运用在全球顶尖的IT产品中,其中就包括了苹果公司的iPhone,同时半导体制造商高通公司以及德州仪器等等巨头都是ARM的客户。伊斯特表示使用ARM的芯片设计生产技术只需要支付数千万美元的专利费,而收购ARM的话则至少需要5
[单片机]
基于ARM+Linux的视频采集编码系统设计
引言 嵌入式系统由于其体积小可便携,较 PC机而言很有优势。随着计算机技术的发展,一些基于PC机的应用也得以在嵌入式系统上实现。由于 USB 接口摄像头价格低廉,性能较好,即插即用,加上Linux下有Video4Linux标准支持对其编程,很容易集成到嵌入式系统,因此嵌入式系统视频采集设备通常用 USB 接口摄像头。 1 芯片介绍 S3C2440 处理器采用ARM920t内核,0.13um的CMOS 标准宏单元和存储器单元,支持高速总线和异步总线模式;具有 1G字节寻址空间;支持外部等待信号延长总线周期;支持掉电时SDRAM 自刷新模式;支持从 NAND flash存储器启动;采用 4KB 内部缓冲器进行启动引导。采用
[单片机]
基于<font color='red'>ARM</font>+Linux的视频采集编码系统设计
Part3_lesson2---ARM指令分类学习
1、算术和逻辑指令 mov、mvn、cmp、tst、sub、add、and、bic 2、比较指令 cmp和tst 3、跳转指令 b和bl 4、移位指令 lsl和ror 5、程序状态字访问指令 msr与mrs指令 6、存储器访问指令 ldr和str
[单片机]
小广播
设计资源 培训 开发板 精华推荐

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

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

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

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