据说位置无关代码只使用相对位置而不是绝对位置,那么在c和汇编中分别如何实现呢?
以char test[] = "string";
为例,如何通过相对地址引用它?
call 1f
1: popl %ebx
紧接着使用ebx
作为基指针,偏移量等于要访问的数据与popl
指令地址之间的距离。
实际上,这通常更加复杂,通常会使用一个小型thunk函数来加载PIC寄存器,例如:
load_ebx:
movl 4(%esp),%ebx
addl $some_offset,%ebx
ret
偏移量的选择是这样的,当thunk返回时,ebx
包含指向程序/库中指定特殊点(通常是全局偏移表的开头)的指针,然后所有随后的ebx
相关访问可以简单地使用所需数据与指定特殊点之间的距离作为偏移量。
在其他架构上,原则上一切都类似,但可能有更简单的方法来加载程序计数器。许多架构只允许您将pc
或ip
寄存器用作相对寻址模式下的普通寄存器。
movl $str, %ecx
,特别是操作数$str
,试图从绝对地址加载。然而,链接器无法确定代码段中的地址,因此无法汇编该指令。该问题的解决方案实现了PIC作为一种hack。问题本身指定了字符串如何变成位置无关的,这是你的问题缺失的部分。char test[] = "string";
本身将按平台默认方式分配,这可能与PIC没有任何关系。 - Potatoswatter$str
不能使用,它如何引用该字符串? - mysql_go$str
紧随call
指令,使其作为返回地址推送到堆栈上。请注意,标签str
实际上根本没有被使用。 - Potatoswatter伪代码如下:
lea str1(pc), r0 ; load address of string relative to the pc (assuming constant strings, maybe)
st r0, test ; save the address in test (test could also be PIC, in which case it could be relative
; to some register)
call 1f
是什么意思? - mysql_go1:
。 - R.. GitHub STOP HELPING ICE