当前位置:网站首页 > R语言数据分析 > 正文

ldr arm指令(arm指令adr)



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,=0x。那编译器在编译该伪指令的时候将会编译成机器码:1110 0101 1001 1111 0000 0000 0001 0100,下面对这个机器码进行分析:

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

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

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之间。

推荐阅读最新更新时间:2024-11-02 10:47

我们可以把可执行文件分为2种情况:存放态和运行态

1.存放态:可执行文件经过烧到存储介质上(flash或磁盘)的分布,此时可执行文件通常有2部分组成,代码段和数据段,代码段又分为可执行代码段 (.text)和只读数据段(.rodata),数据段可以分为初始化数据段(.data)和未初始化代码段(.bss),如下:

+-------------+-----------

| .bss | (ZI)

+-------------+-- 数据段

| .data | (RW)

+-------------+-----------

| .rodata |

|_____________| 代码段(RO)

| .text |

+-------------+-----------

.text代码段,.rodata只读数据段,.bss是未初始化全局变量段, .data是初始化被赋值的全局变量

2.运行态:可执行文件经过装载后就变成为运行态,

当可执行文件装载后, 在RAM中的分布如下:

| ... |

+-------------+-- ZI段结束地址

| ZI 段 |

+-------------+-- ZI段起始地址

| 保留区2 |

+-------------+-- RW段结束地址

| RW 段 |

+-------------+-- RW段起始地址

| 保留区1 |

+-------------+-- RO段结束地址

| RO 段 |

+-------------+-- RO段起始地址

ZI段主要是未初始化数据,RW主要是自动变量,RO主要是代码段。

elf文件

elf文件是UNIX系统实验室开发的,主要包括可执行文件,可充分定位文件与可共享库文件等。按功能分又可分为链接文件和可执行文件。一个elf文件可以使用binutils工具集里面的readelf来查看,比如readelf -h u-boot查看u-boot文件头。

ELF Header:

Magic: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00

Class: ELF32

Data: 2's complement, little endian

Version: 1 (current)

OS/ABI: UNIX - System V

ABI Version: 0

Type: DYN (Shared object file)

Machine: ARM

Version: 0x1

Entry point address: 0x0

Start of program headers: 52 (bytes into file)

Start of section headers: (bytes into file)

Flags: 0x, Version5 EABI

Size of this header: 52 (bytes)

Size of program headers: 32 (bytes)

Number of program headers: 4

Size of section headers: 40 (bytes)

Number of section headers: 25

Section header string table index: 22

概述

binutils是一组二进制工具集,它包括addr2line、ar、gprof、nm、objcopy、objdumpr、ranlib、size、strings、strip等。

ar软件

ar用于建立、修改、提取库文件。ar至少需要两个参数才能运行,比如:

$ ar rv libtest.a add.o minus.o

是指将add.o、minus.o做成库文件libtest.a。其中r是指将文件列表插入归档文件,v是指得到操作版本号。

这样我们引用库文件的时候就可以使用:

$ gcc -o test test.c -ltest

nm软件

nm软件的作用是现实目标文件的信息和属性,比如:

$ nm test.o

U Add

00000000 T main

U Minus

U printf

这里U标志符号未被定义,T表示符号位于代码段,D表示符号位于已初始化数据部分,还有B、t、r、b、R、A、W、d等等。

objcopy软件

objcopy软件用来将某种格式的目标软件转换成另一种格式的目标软件。

比如u-boot使用本软件将u-boot转换成u-boot.srec格式。

objdump软件

本软件可以用来进行反汇编和查看目标文件信息。

ld软件

ld软件用来吧各种目标文件和库文件链接在一起,定位数据和函数的地址,最终生成可执行文件。

链接描述文件介绍:

链接描述文件用于显式的控制ld的链接过程。ld的“-T”选项可以指定链接描述文件的名称。

链接描述文件遵循特定的链接命令语言——linker scripts的语法。比如u-boot.lds

参考文献:

《韦东山——嵌入式Linux应用开发完全手册》第15章

uboot之start.s分析

DENX的u-boot是一个狠庞大的系统,研究透彻u-boot的Make的运作同样是一个狠庞大的工程,目前我仅参考以上两个参考文档对S3C2440的u-boot的编译的Make相关的文件和命令做一个简单说明。如果深入学习《嵌入式Linux应用开发完全手册》是一个很好的指引。

一般针对S3C2440的移植都是参照smdk2410来的,所以在smdk2410的目录,拷贝一个做为smdk2440;

另外,编译后,可以直接查找*.o文件查看已编译选项;

读Makefile可以发现u-boot.lds的用途。

start.S是整个uboot的起始文件。

以上四项《嵌入式Linux应用开发完全手册》已经从源头说明了其组成原理。

一 make smdk2440_config的解析:

一般的,在配置u-boot的时候,我们会输入:

make smdk2440_config

从早期的u-boot版本中可以见到这样的几行:

MKCONFIG=$(SRCTREE)/mkconfig

......

smdk2410_config : unconfig

@$(MKCONFIG) smdk2410 arm arm920t smdk2410 NULL s3c24x0

由此翻译过来,make smdk2440_config就相当于:

https://news.eeworld.com.cn/mcu/mkconfig smdk2410 arm arm920t smdk2410 NULL s3c24x0

二 对于https://news.eeworld.com.cn/mcu/mkconfig smdk2410 arm arm920t smdk2410 NULL s3c24x0的解析:

这个mkconfig是一个shell脚本,它根据传入的参数,做了如下工作:

ln -s asm-$2 asm

ln -s arm-$6 asm-$2/arch

ln -s proc-armv arm-$2/proc

创建config.mk文件

ARCH = arm

CPU = arm920t

BOARD = smdk2410

SOC = s3c24x0

创建于开发板相关的config.h文件

#include

版权声明


相关文章:

  • ifstream在哪个头文件(ifstream写文件)2024-12-08 12:18:04
  • 搭建git服务器(在windows server)(搭建git服务器web界面)2024-12-08 12:18:04
  • codependent no more书有译本吗(code kunst people百度云)2024-12-08 12:18:04
  • hprof怎么读(/hp怎么读)2024-12-08 12:18:04
  • 如何打开目录对话框(在word2007中,如何打开目录对话框)2024-12-08 12:18:04
  • 数组的some和every方法(数组的equals方法)2024-12-08 12:18:04
  • ar是什么意思中文翻译(appear是什么意思中文翻译)2024-12-08 12:18:04
  • dockerdesktop运行错误(docker desktop is shutting down)2024-12-08 12:18:04
  • uchar(uchar范围)2024-12-08 12:18:04
  • score(score翻译)2024-12-08 12:18:04
  • 全屏图片