literal pools是一个用于存储32bit数据的字池,由于机器码的操作数operand2只有12位,所以其能操作的立即数是及其有限的,因此不得不使用一个literal pools来配合指令执行操作。这样一个ldr指令就有可能需要两个32bit的存储空间来完成一个任务。 如果一段代码中需要访问字池时,编译器首先寻找现有的字池,看看里面是否有想要的数据,如果没有则自动在代码段结尾处创建一个字池,当然也可以使用伪指令LTORG来自行创建一个字池。下面说一下字池的位置:
1、字池的位置一般是放在一个代码段的结束位置(一个代码段一般用AREA来定义),一般是在END的后面,或者下一个段(即下一个AREA指令)之前。
2、也可以使用伪指令LTORG自定义一个位置,但一般是在无条件跳转指令的后面,以保证literal pools不会被误当做可执行指令被执行。
3、还有一点,字池的位置要在指令的可执行位置范围内,即要在距离PC指针4k的范围内(原因同样是因为operand2只有12位,即可寻址范围只有4k)。
举例如下:
start
bl func1
bl func2
stop
mov r0,#0x18
ldr r1,=0x20026
; SVC #0x123456
func1
ldr r0,=42
ldr r1,=0x55555555
ldr r2,=0xffffffff
bx lr
LTORG
func2
ldr r3,=0x55555555
ldr r4,=0x66666666
bx lr
LargeTable
SPACE 4200
END
反汇编可以看见
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
就不会出现上面的错误了。
1、字池的位置一般是放在一个代码段的结束位置(一个代码段一般用AREA来定义),一般是在END的后面,或者下一个段(即下一个AREA指令)之前。
2、也可以使用伪指令LTORG自定义一个位置,但一般是在无条件跳转指令的后面,以保证literal pools不会被误当做可执行指令被执行。
3、还有一点,字池的位置要在指令的可执行位置范围内,即要在距离PC指针4k的范围内(原因同样是因为operand2只有12位,即可寻址范围只有4k)。
举例如下:
start
bl func1
bl func2
stop
mov r0,#0x18
ldr r1,=0x20026
; SVC #0x123456
func1
ldr r0,=42
ldr r1,=0x55555555
ldr r2,=0xffffffff
bx lr
LTORG
func2
ldr r3,=0x55555555
ldr r4,=0x66666666
bx lr
LargeTable
SPACE 4200
END
反汇编可以看见
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
就不会出现上面的错误了。