arm汇编中的literal pools

        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 4092
                END
     就不会出现上面的错误了。

Comments

Popular posts from this blog

Basic understanding of TLS-PSK protocol

Differences between ASIC, ASSP and ASIP

Orthogonal instruction set