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

你可能感兴趣的:(arm汇编中的literal pools .)