汇编文字池(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

相关推荐
say_fall20 小时前
8086汇编程序设计_从基础到实战
开发语言·汇编·8086
浩浩测试一下1 天前
LoadPE &&& 原理以及作用 (ASM汇编版本)>>01
汇编·免杀·pe结构·windows编程·二进制逆向·系统loadpe
ThornArmor2 天前
【控制篇】斩断无休止空转:4-bit 指令集里的跳转律令与时序状态机
c语言·汇编·c++·单片机·嵌入式硬件
大阳1232 天前
ARM4.(通过汇编,c语言,固件库点亮LED)
c语言·开发语言·汇编
iCxhust2 天前
8086 汇编 TINY 和 SMALL 编程MODEL区别
汇编·单片机·嵌入式硬件·操作系统·微机原理·8088单板机
say_fall3 天前
从零开始学x86汇编_16位指令系统完全指南
开发语言·汇编·计算机组成·微机原理
txg6665 天前
编译无关的漏洞检测:基于 Transformer 的 LLVM-IR 与汇编鲁棒建模
汇编·深度学习·安全·transformer
浩浩测试一下5 天前
汇编 16位32位64位通用寄存器(逆向分析)
汇编·windows·stm32·单片机·嵌入式硬件·逆向·二进制
浩浩测试一下6 天前
汇编常用的(JCC 串 判断)指令 通用寄存器 标志寄存器 段寄存器(逆向分析)
汇编·通用寄存器·逆向二进制·标志寄存器·段寄存器·串 jcc 常用指令
浩浩测试一下6 天前
汇编 标志位寄存器 (逆向分析 )
c语言·汇编·逆向·windows编程·标志寄存器