博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ARM微处理器的指令集概述(五)—— LDR和ADR分析
阅读量:2343 次
发布时间:2019-05-10

本文共 2078 字,大约阅读时间需要 6 分钟。

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

        在如上的定义中,有两个关键信息:⑴将基于PC相对偏移的地址值读取到寄存器中;⑵被编译器替换成一条合适的指令。ADR指令只能将地址值读取到寄存器中,而不能是其它的立即数,并用只能用一条指令。

        如果在汇编程序中使用ADR R1,ResetHandel语句,其中ResetHandel是汇编程序中的一个标签,此条伪指令的作用是把ResetHandel标签所在的指令地址 读取到寄存器R0中。当汇编器对此条伪指令进行编译的时候,将会编译成机器码:0xE28F100C,转换成二进制就是1110 0010 1000 1111 0001 0000 0000 1100,下面对这个机器码进行分析:

        根据上面的分析,可以看到,编译器在编译的时候把ADR伪指令编译成一个ADD R1,PC,Immediate指令,其中Immediate是一个立即数,数值是ResetHandel语句和此条伪指令之间的差值,由编译器自动算 出。由于立即数寻址的约束,这个Immediate存在一定的约束,所以会出现定义中所说的不能用一条指令实现。

 

 

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

        与ARM指令的LDR相比,伪指令的LDR的参数有"="号。

        在如上的定义中,有三个关键信息:⑴用于加载32们的立即数或一个地址值到指定寄存器;⑵被编译器替换成一条合适的指令;⑶优先使用MOV或MVN指令代替该指令。

        如果使用MOV指令,那就使用立即数寻址的方式,但是立即数寻址存在一个范围白约束,所以不是所以的常数都可以使用立即数寻址白方式。当不能使用立 即数寻址方式时,就把常量放入文字池,使用一条程序相对于PC寻址的LDR指令把文字池的内容读取到寄存器中。立即数和地址值的操作方式是一样的。

        如果有伪指令:LDR R0,=0x123456。那编译器在编译该伪指令的时候将会编译成机器码:1110 0101 1001 1111 0000 0000 0001 0100,下面对这个机器码进行分析:

由上面分析可知,伪指令LDR R0,=0x123456其实就是被编译成LDR R0,[PC,Immediate]。其中立即数0x123456被储存在一个文字池中,他的地址和指令LDR R0,[PC,Immediate]的地址之前差了Immediate。因此指令LDR R0,[PC,Immediate]就可以把立即数0x123456读取到R0中了。

原文:http://tanglei9098.blog.163.com/blog/static/502021152010312104430781/

LDR 是ARM中的指令,也是伪指令。

当用 LDR r, =imd  // r 为寄存器, imd为立即数

LDR 是一条伪指令。编译器会根据 立即数的大小,决定用 ldr 指令或者是mov或mvn指令。

当imd能用mov或者mvn操作时,就将它翻译成一条mov或mvn指令。当imd大于mov或mvn能够操作的数时,编译器会将imd存在一个内存单元中,然后再用一条ldr指令加载这个内存单元的的值到寄存器中。

LDR r, label  和 LDR r, =label的区别:

LDR r, =label 会把label表示的值加载到寄存器中,而LDR r, label会把label当做地址,把label指向的地址中的值加载到寄存器中。

譬如 label的值是 0x8000, LDR r, =label会将 0x8000加载到寄存器中,而LDR r, label则会将内存0x8000处的值加载到寄存器中。

ADR 和 ADRL 伪指令:

ADR 和 ADRL 伪指令用于将一个地址加载到寄存器中。

ADR为小范围的地址读取伪指令。ADR指令将基于PC相对偏移的地址值读取到寄存器中。在汇编编译源程序时,ADR伪指令被编译器替换在一条合适 的指令,通常,编译器用一条ADD指令或SUB指令来实现该ADR伪指令的功能,若不能使用一条指令实现,则产生错误。其能加载的地址范围,当为字节对齐 时,是-1020~1020,当为非字对齐时在-255~255之间。

ADRL是中等范围的地址读取指令。会被编译器翻译成两条指令。如果不能用两条指令表示,则产生错误。

ADRL能加载的地址范围当为非字节对齐时是-64K~64K之间;当为字节对齐时是-256K~256K之间。

转载地址:http://hhfvb.baihongyu.com/

你可能感兴趣的文章
AngularJS ngClass条件
查看>>
连字符分隔的大小写是什么? [关闭]
查看>>
为什么Java中没有SortedList?
查看>>
在Go中表示枚举的惯用方法是什么?
查看>>
在React中显示或隐藏元素
查看>>
暂存已删除的文件
查看>>
为什么需要在脚本文件的开头加上#!/ bin / bash?
查看>>
ReactJS-每次调用“ setState”时都会调用渲染吗?
查看>>
如何解决错误:使用nodejs时监听EADDRINUSE?
查看>>
@import vs #import - iOS 7
查看>>
如何使用C#解析JSON?
查看>>
ng-if和ng-show / ng-hide有什么区别
查看>>
用Java复制文件的标准简洁方法?
查看>>
管理webpack中的jQuery插件依赖项
查看>>
删除可能不存在的文件的大多数pythonic方式
查看>>
如何在Eclipse中为Java文本编辑器更改字体大小?
查看>>
我们应该@Override接口的方法实现吗?
查看>>
ng-repeat定义次数而不是重复数组?
查看>>
选择语句以查找某些字段的重复项
查看>>
引导程序中“col-md-4”,“col-xs-1”,“col-lg-2”中数字的含义
查看>>