我有一个64位操作系统,我正在构建一个使用rip相对寻址的64位程序。我的问题是我无法使用.lcomm指令分配超过2GB的数据。有没有办法分配超过2GB的天然气,还是我必须使用不同的指令?
.lcomm array,2*1024*1024*1024
#>=2GB doesn't work
#error:additional relocation overflows omitted from the output
答案 0 :(得分:1)
RIP相对位移符号为32位。默认代码模型是" small",其中所有静态代码/数据都在低2GB的虚拟地址空间中,因此RIP相对寻址模式或rel32分支/调用可以从任何地方到达任何符号。 (或者对于小型PIC,一切都在2GB以内,但是你让ASLR把它放在内存中。)
检查x86-64 System V ABI,了解如何使用默认" small"以外的代码模型。 Where is the x86-64 System V ABI documented?
如果它只是这一个巨大的数组,你应该使用某种链接器脚本或其他东西来安排它是唯一超出低2G的东西,所以其他一切仍然可以假设小代码模型。即将它放在BSS的末尾高于其他所有位置,因此array
符号可以从低2G中的任何位置与所有其他标签一起从RIP相对寻址。
但是数组的结尾可能无法实现而不会导致问题,因为您将基地址放入寄存器并对其进行索引。如果你在C中编写类似array[1ULL<<32] = 1;
的内容并且编译器正在使用小代码模型,那么你只会得到一个链接器错误,因此它会像movb $1, array+1<<32 (%rip)
那样发出asm,这当然赢了工作