资料介绍
ARM处理器支持位置无关的程序设计,这种程序加载到存储器的任意地址空间都可以正常运行,其设计方法在嵌入式应用系统开发中具有重要的作用。尤其在裸机状态下开发Bootloader程序及进行内核初始化设计;利用位置无关的程序设计方法还可以在具体应用中用于构建高效率动态链接库,因而了解位置无关的程序设计方法,有助于开发人员设计出结构简单、清晰的应用程序。
应用程序必须经过编译、汇编和链接后才变成可执行文件,在链接时,要对所有目标文件进行重定位(relocatiON),建立符号引用规则,同时为变量、函数等分配运行地址。当程序执行时,系统必须把代码加载到链接时所指定的地址空间,以保证程序在执行过程中对变量、函数等符号的正确引用,使程序正常运行。在具有操作系统的系统中,重定位过程由操作系统自动完成。
在设计Bootloader程序时,必须在裸机环境中进行,这时Bootloader映像文件的运行地址必须由程序员设定。通常情况下,将Bootloader程序下载到ROM的0x0地址进行启动,而在大多数应用系统中,为了快速启动,首先将Bootloader程序拷贝到SDRAM中再运行。一般情况下,这两者的地址并不相同,程序在SDRAM中的地址重定位过程必须由程序员完成。实际上,由于Bootloader是系统上电后要执行的第一段程序,Bootloader程序的拷贝和在这之前的所有工作都必须由其自身来完成,而这些指令都是在ROM中执行的。也就是说,这些代码即使不在链接时所指定的运行时地址空间,也可以正确执行。这就是位置无关代码,它是一段加载到任意地址空间都能正常执行的特殊代码。
位置无关代码常用于以下场合:
程序在运行期间动态加载到内存;
程序在不同场合与不同程序组合后加载到内存(如共享的动态链接库);
在运行期间不同地址相互之间的映射(如Bootloader程序)。
虽然在用GCC编译时,使用-fPIC选项可为C语言产生位置无关代码,但这并不能修正程序设计中固有的位置相关性缺陷。特别是汇编语言代码,必须由程序员遵循一定的程序设计准则,才能保证程序的位置无关性。
ARM程序的位置无关可执行文件PIE(PositionIndependent Executable)包括位置无关代码PIC和位置无关数据PID(PositionIndependent Data)两部分。
PID主要针对可读写数据段(.data段),其中保存已赋初值的全局变量。为实现其位置无关性,通常使用寄存器R9作为静态基址寄存器,使其指向该可读写段的首地址,并使用相对于基址寄存器的偏移量来对该段的变量进行寻址。这种方法常用于为可重入程序的多个实例产生多个独立的数据段。在程序设计中,一般不必考虑可读写段的位置无关性,这主要是因为可读写数据主要分配在SDRAM中。
PIC包括程序中的代码和只读数据(.text段),为保证程序能在ROM和SDRAM空间都能正确运行(如裸机状态下的Bootloader程序),必须采用位置无关代码程序设计。
PIC遵循只读段位置无关ROPI(ReadOnly Position Independence)的ATPCS(ARMThumb Procedure Call STandard)的程序设计规范:
程序设计规范
(1) 程序设计规范1
引用同一ROPI段或相对位置固定的另一ROPI段中的符号时,必须是基于PC的符号引用,即使用相对于当前PC的偏移量来实现跳转或进行常量访问。
① 位置无关的程序跳转。在ARM汇编程序中,使用相对跳转指令B/BL实现程序跳转。指令中所跳转的目标地址用基于当前PC的偏移量来表示,与链接时分配给地址标号的绝对地址值无关,因而代码可以在任何位置进行跳转,实现位置无关性。
另外,还可使用ADR或ADRL伪指令将地址标号值读取到PC中实现程序跳转。这是因为ADR或ADRL等伪指令会被编译器替换为对基于PC的地址值进行操作,但这种方式所能读取的地址范围较小,并且会因地址值是否为字对齐而异。
但在ARM程序中,使用LDR等指令直接将地址标号值读取到PC中实现程序跳转不是位置无关的。例如: LDR PC, =main
上面的伪指令编译后的结果为: LDR PC, [PC, OFFSET_TO_LPOOL]
? LPOOL
DCD main
可见,虽然LDR是把基于PC的一个存储单元LPOOL的内容加载到PC中,但该存储单元中保存的却是链接时所决定的main函数入口的绝对地址,所以main函数实际所在的段不是位置无关。
② 位置无关的常量访问。在应用程序中,经常要读写相关寄存器以完成必要的硬件初始化。为增强程序的可读性,利用EQU伪指令对一些常量进行赋值,但在访问过程中,必须实现位置无关性。下面以PXA270的GPIO初始化介绍位置无关的常量访问方法。
GPIO_BASE EQU 0x40e00000; GPIO基址寄存器地址
GPDR0 EQU 0x00c; 相对于GPIO基址寄存器的偏移量
init_GPDR0 EQU 0xfffbfe00; 寄存器GPDR0初值
LDR R1, =GPIO_BASE
LDR R0, =init_GPDR0
STR R0, [R1, #GPDR0]
上述汇编代码段经编译后的结果为:
LDR R1, [PC, OFFSET_TO_GPIO_BASE]
LDR R0, [PC, OFFSET_TO_init_GPDR0]
STR R0, [R1, #0xc]?
GPIO_BASE
DCD 0x40e00000
GPDR0
DCD 0x00c
init_GPDR0
DCD 0xfffbfe00
可见,LDR伪指令实际上使用基于PC的偏移量来对符号常量GPIO_BASE和init_GPDR0进行引用,因而是位置无关的。由此可以得出如下结论:使用LDR伪指令将一个常量读取到非PC的其他通用寄存器中可实现位置无关的常量访问;但将一个地址值读取到PC中进行程序跳转时,跳转目标则是位置相关的。
(2) 程序设计规范2
其他被ROPI段中的代码引用的必须是绝对地址,或者是基于可读写位置无关(RWPI)段的静态基址寄存器的可写数据。
使用绝对地址只能引用被重定位到特定位置的代码段中的符号,通过在位置无关代码中引入绝对地址,可以让程序跳转到指定位置。例如,假设Bootloader的阶段1将其自身代码拷贝到链接时所指定的SDRAM地址空间后,当要跳转到阶段2的C程序入口时,可以使用指令“LDR PC, =main”跳转到程序在SDRAM中的main函数入口地址开始执行。这是因为程序在编译链接时给main函数分派绝对地址,系统通过将main函数的绝对地址直接赋给PC实现程序跳转。如果使用相对跳转指令“B main”,那么只会跳转到启动ROM内部的main函数入口。
应用程序必须经过编译、汇编和链接后才变成可执行文件,在链接时,要对所有目标文件进行重定位(relocatiON),建立符号引用规则,同时为变量、函数等分配运行地址。当程序执行时,系统必须把代码加载到链接时所指定的地址空间,以保证程序在执行过程中对变量、函数等符号的正确引用,使程序正常运行。在具有操作系统的系统中,重定位过程由操作系统自动完成。
在设计Bootloader程序时,必须在裸机环境中进行,这时Bootloader映像文件的运行地址必须由程序员设定。通常情况下,将Bootloader程序下载到ROM的0x0地址进行启动,而在大多数应用系统中,为了快速启动,首先将Bootloader程序拷贝到SDRAM中再运行。一般情况下,这两者的地址并不相同,程序在SDRAM中的地址重定位过程必须由程序员完成。实际上,由于Bootloader是系统上电后要执行的第一段程序,Bootloader程序的拷贝和在这之前的所有工作都必须由其自身来完成,而这些指令都是在ROM中执行的。也就是说,这些代码即使不在链接时所指定的运行时地址空间,也可以正确执行。这就是位置无关代码,它是一段加载到任意地址空间都能正常执行的特殊代码。
位置无关代码常用于以下场合:
程序在运行期间动态加载到内存;
程序在不同场合与不同程序组合后加载到内存(如共享的动态链接库);
在运行期间不同地址相互之间的映射(如Bootloader程序)。
虽然在用GCC编译时,使用-fPIC选项可为C语言产生位置无关代码,但这并不能修正程序设计中固有的位置相关性缺陷。特别是汇编语言代码,必须由程序员遵循一定的程序设计准则,才能保证程序的位置无关性。
ARM程序的位置无关可执行文件PIE(PositionIndependent Executable)包括位置无关代码PIC和位置无关数据PID(PositionIndependent Data)两部分。
PID主要针对可读写数据段(.data段),其中保存已赋初值的全局变量。为实现其位置无关性,通常使用寄存器R9作为静态基址寄存器,使其指向该可读写段的首地址,并使用相对于基址寄存器的偏移量来对该段的变量进行寻址。这种方法常用于为可重入程序的多个实例产生多个独立的数据段。在程序设计中,一般不必考虑可读写段的位置无关性,这主要是因为可读写数据主要分配在SDRAM中。
PIC包括程序中的代码和只读数据(.text段),为保证程序能在ROM和SDRAM空间都能正确运行(如裸机状态下的Bootloader程序),必须采用位置无关代码程序设计。
PIC遵循只读段位置无关ROPI(ReadOnly Position Independence)的ATPCS(ARMThumb Procedure Call STandard)的程序设计规范:
程序设计规范
(1) 程序设计规范1
引用同一ROPI段或相对位置固定的另一ROPI段中的符号时,必须是基于PC的符号引用,即使用相对于当前PC的偏移量来实现跳转或进行常量访问。
① 位置无关的程序跳转。在ARM汇编程序中,使用相对跳转指令B/BL实现程序跳转。指令中所跳转的目标地址用基于当前PC的偏移量来表示,与链接时分配给地址标号的绝对地址值无关,因而代码可以在任何位置进行跳转,实现位置无关性。
另外,还可使用ADR或ADRL伪指令将地址标号值读取到PC中实现程序跳转。这是因为ADR或ADRL等伪指令会被编译器替换为对基于PC的地址值进行操作,但这种方式所能读取的地址范围较小,并且会因地址值是否为字对齐而异。
但在ARM程序中,使用LDR等指令直接将地址标号值读取到PC中实现程序跳转不是位置无关的。例如: LDR PC, =main
上面的伪指令编译后的结果为: LDR PC, [PC, OFFSET_TO_LPOOL]
? LPOOL
DCD main
可见,虽然LDR是把基于PC的一个存储单元LPOOL的内容加载到PC中,但该存储单元中保存的却是链接时所决定的main函数入口的绝对地址,所以main函数实际所在的段不是位置无关。
② 位置无关的常量访问。在应用程序中,经常要读写相关寄存器以完成必要的硬件初始化。为增强程序的可读性,利用EQU伪指令对一些常量进行赋值,但在访问过程中,必须实现位置无关性。下面以PXA270的GPIO初始化介绍位置无关的常量访问方法。
GPIO_BASE EQU 0x40e00000; GPIO基址寄存器地址
GPDR0 EQU 0x00c; 相对于GPIO基址寄存器的偏移量
init_GPDR0 EQU 0xfffbfe00; 寄存器GPDR0初值
LDR R1, =GPIO_BASE
LDR R0, =init_GPDR0
STR R0, [R1, #GPDR0]
上述汇编代码段经编译后的结果为:
LDR R1, [PC, OFFSET_TO_GPIO_BASE]
LDR R0, [PC, OFFSET_TO_init_GPDR0]
STR R0, [R1, #0xc]?
GPIO_BASE
DCD 0x40e00000
GPDR0
DCD 0x00c
init_GPDR0
DCD 0xfffbfe00
可见,LDR伪指令实际上使用基于PC的偏移量来对符号常量GPIO_BASE和init_GPDR0进行引用,因而是位置无关的。由此可以得出如下结论:使用LDR伪指令将一个常量读取到非PC的其他通用寄存器中可实现位置无关的常量访问;但将一个地址值读取到PC中进行程序跳转时,跳转目标则是位置相关的。
(2) 程序设计规范2
其他被ROPI段中的代码引用的必须是绝对地址,或者是基于可读写位置无关(RWPI)段的静态基址寄存器的可写数据。
使用绝对地址只能引用被重定位到特定位置的代码段中的符号,通过在位置无关代码中引入绝对地址,可以让程序跳转到指定位置。例如,假设Bootloader的阶段1将其自身代码拷贝到链接时所指定的SDRAM地址空间后,当要跳转到阶段2的C程序入口时,可以使用指令“LDR PC, =main”跳转到程序在SDRAM中的main函数入口地址开始执行。这是因为程序在编译链接时给main函数分派绝对地址,系统通过将main函数的绝对地址直接赋给PC实现程序跳转。如果使用相对跳转指令“B main”,那么只会跳转到启动ROM内部的main函数入口。
下载该资料的人也在下载
下载该资料的人还在阅读
更多 >
- 基于ARM处理器的TFT-LCD显示系统 34次下载
- 基于ARM处理器的禽舍环境监控系统 31次下载
- 增量式PID控制算法程序设计方案下载 7次下载
- 使用ARM处理器设计电子式互感器数据采集系统的论文说明 7次下载
- ARM嵌入式处理器的GNU工具应用程序免费下载 7次下载
- 基于ARM7核处理器VxWorks系统BSP设计方案解析 35次下载
- ARM体系结构下的程序设计经验 5次下载
- 嵌入式软件开发之基于ARM处理器的嵌入式系统设计方案解析 1次下载
- 嵌入式系统开发基础_基于ARM9微处理器C语言程序设计(第二版) 0次下载
- ARM嵌入式处理器结构与应用基础_免费下载 324次下载
- 基于ARM 微处理器的故障记录系统 57次下载
- 基于ARM的BSP程序设计方案
- ARM程序设计基础教材
- ARM程序设计基础
- ARM微处理器的编程模型
- 解析PLC梯形图程序设计 1402次阅读
- 基于pSOS和TM1300媒体处理器实现多媒体通信系统的应用方案 2081次阅读
- 采用ARM EP9315处理器实现P0104总线的应用方案 2895次阅读
- ARM协处理器接口 1420次阅读
- 各类ARM处理器的区别及应用 6045次阅读
- 基于嵌入式处理器PowerPC7447的设计方案 1128次阅读
- 解答arm处理器的七种工作模式 1.6w次阅读
- 浅谈arm处理器的优势 1.2w次阅读
- 解答arm是什么/arm处理器采用什么技术 8078次阅读
- 运用ARM处理器软件工具出错,会带来什么样的结果? 705次阅读
- 液晶显示屏设计方案:基于Nios嵌入式软核处理器 1081次阅读
- arm的协处理器有几个?ARM协处理器详解 8823次阅读
- 浅谈ARM处理器的特点和体系结构 1.7w次阅读
- 基于ARM处理器的高效异常处理解决方案 1286次阅读
- PicoBlaze处理器IP Core的原理与应用 851次阅读
下载排行
本周
- 1HFSS电磁仿真设计应用详解PDF电子教程免费下载
- 24.30 MB | 126次下载 | 1 积分
- 2H桥中的电流感测
- 545.39KB | 7次下载 | 免费
- 3雷达的基本分类方法
- 1.25 MB | 4次下载 | 4 积分
- 4I3C–下一代串行通信接口
- 608.47KB | 3次下载 | 免费
- 5电感技术讲解
- 827.73 KB | 2次下载 | 免费
- 6从 MSP430™ MCU 到 MSPM0 MCU 的迁移指南
- 1.17MB | 2次下载 | 免费
- 7有源低通滤波器设计应用说明
- 1.12MB | 2次下载 | 免费
- 8RA-Eco-RA2E1-48PIN-V1.0开发板资料
- 35.59 MB | 2次下载 | 免费
本月
- 12024年工控与通信行业上游发展趋势和热点解读
- 2.61 MB | 763次下载 | 免费
- 2HFSS电磁仿真设计应用详解PDF电子教程免费下载
- 24.30 MB | 126次下载 | 1 积分
- 3继电保护原理
- 2.80 MB | 36次下载 | 免费
- 4正激、反激、推挽、全桥、半桥区别和特点
- 0.91 MB | 32次下载 | 1 积分
- 5labview实现DBC在界面加载配置
- 0.57 MB | 21次下载 | 5 积分
- 6在设计中使用MOSFET瞬态热阻抗曲线
- 1.57MB | 15次下载 | 免费
- 7GBT 4706.1-2024家用和类似用途电器的安全第1部分:通用要求
- 7.43 MB | 13次下载 | 免费
- 8PADS-3D库文件
- 2.70 MB | 10次下载 | 2 积分
总榜
- 1matlab软件下载入口
- 未知 | 935113次下载 | 10 积分
- 2开源硬件-PMP21529.1-4 开关降压/升压双向直流/直流转换器 PCB layout 设计
- 1.48MB | 420061次下载 | 10 积分
- 3Altium DXP2002下载入口
- 未知 | 233084次下载 | 10 积分
- 4电路仿真软件multisim 10.0免费下载
- 340992 | 191360次下载 | 10 积分
- 5十天学会AVR单片机与C语言视频教程 下载
- 158M | 183329次下载 | 10 积分
- 6labview8.5下载
- 未知 | 81578次下载 | 10 积分
- 7Keil工具MDK-Arm免费下载
- 0.02 MB | 73804次下载 | 10 积分
- 8LabVIEW 8.6下载
- 未知 | 65985次下载 | 10 积分
评论
查看更多