如何在 gas 汇编程序中分配超过 2GB 的内存?

How can I allocate more than 2GB of memory in gas assembler?

我有一个 64 位 OS,我正在构建一个使用 rip-relative 寻址的 64 位程序。我的问题是我无法使用 .lcomm 指令分配超过 2GB 的数据。有没有办法分配超过 2GB 的 gas,或者我必须使用不同的指令?

.lcomm array,2*1024*1024*1024 
#>=2GB doesn't work
#error:additional relocation overflows omitted from the output

RIP 相对位移是有符号的 32 位。默认代码模型是"small",其中所有静态code/data都在虚拟地址space的低2GB,因此RIP-relative寻址模式或rel32分支/调用可以到达任何符号从任何地方。 (或者对于小型 PIC,所有内容最多在 2GB 以内,但你让 ASLR 将其放在内存中的任何位置。)

查看 x86-64 System V ABI,了解如何使用默认 "small" 以外的代码模型。 Where is the x86-64 System V ABI documented?.


如果只是这个巨大的数组,您可能应该使用某种链接描述文件或其他东西来安排 it 成为唯一延伸到低 2G 之外的东西,所以其他一切仍然可以采用小代码模型。即,将它放在 BSS 的末尾,高于其他所有内容,因此 array 符号与所有其他标签一起可从低 2G 中任何位置的代码进行相对 RIP 寻址。

但是数组的末尾可能无法到达而不会导致问题,因为您将基地址放入寄存器并对其进行索引。如果您在 C 中编写类似 array[1ULL<<32] = 1; 的内容并且编译器正在使用小型代码模型,那么您只会收到链接器错误,因此它会发出像 movb , array+1<<32 (%rip) 这样的 asm,这当然不会工作。