屌丝学arm汇编-05-编译器如何利用pc指针生成PIC(位置无关码)

2019-04-15 12:05发布

首先来2个问题 1.编译器如何处理伪指令,例如ldr。首先伪指令不是真实的指令,这样说有些模糊。伪指令的执行者不是arm cpu,而是编译器。这个描述准确点,但是编译器只是把伪 指令做了转化,转化成arm指令,最终还是有arm cpu来执行。在C语言中  #define    TEST    (5 - 3)  这里(5- 3)会由编译器计算好,将结果放到最终生成的执行程序中,一般在code的.text段,再最终由arm cpu来执行。 2.编译器和arm 在生成PIC位置无关码中,各自做了哪些事情,是我这个demo想去演示。 demo的作用通过一个buf指针,利用pc指针和buf的相对便宜来对buf进行定位,并完成对其中数据的修改。 下载路径:http://download.csdn.net/detail/losting_boy/9620735 AREA addr01, CODE, READONLY entry CODE32 start ldr r0, =(testcode16 + 1) BX r0 CODE16 testcode16 mov r5,#1 ldr r3,=handleBuf_ptr - 0x8016 ;(1)注意这里 LSLS r5,r5,#2 add r3,pc ;通过pc 来加上 dcd 的handleBuf_ptr 于当前的位置偏移来获取变量地址 ldr r3,[r3] ;对handleBuf_ptr进行取值,获得最终buf的地址,存到r3 tag movs r1,#0x80 ;这里的地址是0x8016 str r0,[r5,r3] stop b . AREA data1,DATA,READWRITE handlebuf DCB 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4 handleBuf_ptr DCD handlebuf END
注意点: (1)0x8016怎么来的,由编译器计算得来,这里是我模拟编译器,通过反编译计算得来。 (2)ldr r3,=handleBuf_ptr - 0x8016,因为ldr是伪指令,编译器翻译成了 ldr   r3,0x8028,这里0x8028存储的是编译器计算的结果,如下,arm cpu执行从这个地址取结果 (3)thumb pc = 当前执行地址 + 4, code 32 pc = 当前 + 8 ,具体不解释 (4)handlebuf代表一个buf的首地址,handleBuf_ptr是指向handlebuf的指针。这里可以理解为标号,等效于地址。cpu是不区分那些是指针,哪些是指针的指针啥的,只是内存地址和地址中存放的数据 几个坑: 坑1:ldr r3,=handleBuf_ptr - 0x8016 ,换成ldr r3,=(handleBuf_ptr - 0x8016)结果不对          坑2:ldr r3,=handleBuf_ptr - 0x8016 ,换成ldr r3,=(handleBuf_ptr - tag)结果不对 具体原因,这部分要看编译器如何处理。不深究,不同编译器处理有些许差异