为何GCC与Clang对16MB以上数组停止使用RIP相对寻址加载?
RIP相对寻址在大数组访问中的编译器行为疑问
我知道RIP相对寻址理论上支持最大2GB的偏移量,但GCC(14.2)和Clang(19.1.0)在访问超过16MB的数组时,却不再采用这种寻址方式。
测试代码
const int size = 1 << 22; int small_array[size]; // 生成*6字节mov指令* int load_small_arry() { return small_array[(sizeof(small_array)/sizeof(int)-1)]; } int big_array[size + 1]; // Clang生成*5字节mov + 6字节mov* // GCC生成*9字节mov* int load_big_arry() { return big_array[(sizeof(big_array)/sizeof(int)-1)]; }
GCC生成的汇编代码
(Clang的生成结果逻辑类似,同样未使用RIP相对寻址)
load_small_arry(): mov eax,DWORD PTR [rip+0x0] # 6 <load_small_arry()+0x6> R_X86_64_PC32 small_array+0xfffff8 ret nop WORD PTR [rax+rax*1+0x0] load_big_arry(): movabs eax,ds:0x0 R_X86_64_64 big_array+0x1000000 ret
这种替代方式的编码长度更长,我无法理解编译器为何会优先选择它。
内容的提问来源于stack exchange,提问作者Joseph Garvin
相关产品推荐
相关产品推荐

