汇编文字池(literal pool)

什么是文字池

文字池(Literal pools)是汇编代码段中的用来存放常量数据而非可执行代码的内存块。有时配合LTORG,确保文字池位于程序寻址范围内。

为什么需要文字池

当在一条指令中使用一个4字节的常量数据的时候,由于ARM指令集是定长的(ARM指令4字节、Thumb指令2字节),可能无法把这4字节的常量数据编码在指令中。

此时,ARM编译器/汇编器就会在代码段中分配一块内存,并把这个4字节的数据保存起来,之后,再使用一条指令把这个常量数据加载到寄存器中参与运算。

C程序中,文字池的分配是由编译器在编译时自行分配的,但是,在写汇编程序时,开发人员可以自己进行文字池的分配,如果没有自己分配,汇编器也会代劳。

ldr rd, =value 伪指令可在单个指令中使用任何 32 位常数,此伪指令可生成超出MOV和MVN指令范围的常数。

1、如果可以用MOV或MVN 指令构造该常数,则汇编器会生成适当的指令。

2、如果不能用单个MOV或MVN 指令构造该常数,则汇编器会执行下列操作:将该常数放入文字池中,生成一个使用PC相对地址的 LDR 指令,从文字池中读取该常数。

说的通俗一点,如果 ldr Rd, =value 能够被转换成MOV 或者MVN指令,则汇编器将转换成它成为相应的指令,如果不能被转换,则汇编器会将value存放在文字池中,并且产生一个LDR指令操作。

文字池的位置

汇编器默认把文字池放在每一个代码段的末尾处。

代码段的末尾的确定或者是由汇编源文件尾部的指示符END确定,或者由相邻代码段的起始行AREA确定(被include的文件中的END并不算)。

在大的代码段中(通俗理解为这个段中的代码量比较多),默认文字池在最后,可能与代码section中一条或多条LDR伪指令的距离很远,可能超出LDR伪指令操作数的寻址范围。

当伪指令是32位时,在ARM或Thumb代码中,必须小于4K字节,文字池常量数据的位置可以是在伪指令的前面,也可以是在伪指令的后面。当伪指令是16位Thumb指令时,必须小于1K字节,且文字池必须位于伪指令的后面。

ldr Rd, =value 伪指令需要一个文字池来存放立即数常量时,汇编器会检查已经存在的文字池中是否有相同的常量并且检查文字池是否在伪指令允许寻址的范围内。如果条件满足,汇编器引用这个满足条件的常量,否则汇编器会尝试把该常量值放到文字池未用的空间中。如果空间地址超出伪指令的寻址范围,汇编器会产生一条错误信息。这种情况下,程序员必须得自己用指示符LTORG在代码中设置增加一个文字池。指示符LTORG放在导致错误的伪指令后面,并且位于伪指令LDR的有效寻址范围内(一般节的代码量不是特别大的情况下,可以放于中间位置)。而且要保证设置的这个文字池,处理器执行代码的时候不会执行到这个地址。当然LTORG不是随便放置的,随便放置有可能被当成汇编指令来执行,需要放置在无条件跳转的汇编指令之后或者子程序返回指令的后面。

关于LTORG

LTORG用于声明一个文字池,在使用LDR伪指令的时候,要在适当的地址加入LTORG声明文字池,这样就会把要加载的数据保存在文字池内,再用ARM的加载指令读出数据。 (若没有使用LTORG声明文字池,则汇编器会在程序未尾自动声明)。

伪指令应用举例如下:

反汇编可以看见

29 00000018 E3E02000 ldr r2,=0xffffffff ``

30 0000001C E12FFF1E bx lr ``

31 00000020 00020026 ``

55555555 LTORG

32 00000028 func2

subroutine结尾处,bx lr后面使用了两个32bit的存储单元用来存放stop中的0x20026以及func1中的0x55555555。``(0xffffffff可以用指令mvn解决),但是该段代码编译后会在指令ldr r4,=0x66666666处产生一个错误,``即literal pools is too distant, use LTORG to assemble it within 4KB。即literal pools超出可寻址范围4kB。 ``如果此时将LargeTable后面的SPACE 4200改成4092(因为bx lr要占用一个32bit空间), 就不会出现上面的错误了。

LargeTable ``

SPACE 4200 END

相关推荐
独小乐2 天前
012.整体框架适配SDRAM|千篇笔记实现嵌入式全栈/裸机篇
c语言·汇编·笔记·单片机·嵌入式硬件·arm·gnu
C++ 老炮儿的技术栈2 天前
GCC编译时无法向/tmp 目录写入临时汇编文件,因为设备空间不足,解决
linux·运维·开发语言·汇编·c++·git·qt
cch89182 天前
Java vs 汇编:高级与低级的终极对决
java·开发语言·汇编
2301_789015622 天前
C++:智能指针
c语言·开发语言·汇编·c++·智能指针
独小乐4 天前
007.GNU C内联汇编杂谈|千篇笔记实现嵌入式全栈/裸机篇
linux·c语言·汇编·单片机·嵌入式硬件·arm·gnu
Lzh编程小栈7 天前
数据结构与算法之队列深度解析:循环队列+C 语言硬核实现 + 面试考点全梳理
c语言·开发语言·汇编·数据结构·后端·算法·面试
cch89188 天前
汇编与C语言:底层对话VS高效指挥
c语言·开发语言·汇编
jwn9998 天前
PHP vs 汇编:编程语言的两极对决
开发语言·汇编·php
cch89188 天前
汇编vs易语言:底层与中文编程终极对决
汇编
cch89189 天前
汇编VS高级语言:从硬件操控到高效开发
汇编