簡體   English   中英

gcc / clang如何假設字符串常量的地址是32位?

[英]How can gcc/clang assume a string constant's address is 32-bit?

如果我編譯這個程序:

#include <stdio.h>

int main(int argc, char** argv) {
    printf("hello world!\n");
    return 0;
}

對於x86-64,asm輸出使用movl $.LC0, %edi / call puts 請參閱godbolt上的完整asm輸出/編譯選項 。)

我的問題是:GCC如何知道字符串的地址可以適合32位立即數操作數? 為什么不需要使用movabs $.LC0, %rdi (即mov r64, imm64 ,不是零或符號擴展的imm32 )。

AFAIK,沒有任何跡象表明加載器必須決定在任何特定地址加載數據部分。 如果字符串存儲在1ULL << 32以上的某個地址,那么movl將忽略更高的位。 我對clang有類似的行為,所以我不認為這是GCC獨有的。


我關心的原因是我想創建自己的數據段,它存在於我選擇的任意地址(可能超過2 ^ 32)的內存中。

在GCC手冊中:

https://gcc.gnu.org/onlinedocs/gcc-4.5.3/gcc/i386-and-x86_002d64-Options.html

3.17.15 Intel 386和AMD x86-64選項

-mcmodel =小

為小代碼模型生成代碼:程序及其符號必須鏈接在地址空間的低2 GB中。 指針是64位。 程序可以靜態或動態鏈接。 這是 默認代碼模型。

-mcmodel = kernel為內核代碼模型生成代碼。 內核運行在負2 GB的地址空間中。 該模型必須用於Linux內核代碼。

-mcmodel =中等

為介質模型生成代碼:程序鏈接在地址空間的低2 GB中。 小符號也放在那里。 大小大於-mlarge-data-threshold的符號被放入大數據或bss部分,並且可以位於2GB以上。 程序可以靜態或動態鏈接。

-mcmodel =大

為大型模型生成代碼:此模型不會對部分的地址和大小做出任何假設。


https://gcc.gnu.org/onlinedocs/gcc/AArch64-Options.html

3.18.1 AArch64選項

-mcmodel =微小

生成微小代碼模型的代碼。 程序及其靜態定義的符號必須在1GB之內。 指針是64位。 程序可以靜態或動態鏈接。 這個模型沒有完全實現,大多被視為“小”。

-mcmodel =小

為小代碼模型生成代碼。 程序及其靜態定義的符號必須在4GB之內。 指針是64位。 程序可以靜態或動態鏈接。 這是 默認代碼模型

-mcmodel =大

為大型代碼模型生成代碼。 這不會對部分的地址和大小做出任何假設。 指針是64位。 程序只能靜態鏈接。

我可以確認這是在64位編譯時發生的:

gcc -O1 foo.c

然后objdump -d a.out (另請注意printf("%s\\n")可以優化為puts ):

0000000000400536 <main>:
  400536:       48 83 ec 08             sub    $0x8,%rsp
  40053a:       bf d4 05 40 00          mov    $0x4005d4,%edi
  40053f:       e8 cc fe ff ff          callq  400410 <puts@plt>
  400544:       b8 00 00 00 00          mov    $0x0,%eax
  400549:       48 83 c4 08             add    $0x8,%rsp
  40054d:       c3                      retq   
  40054e:       66 90                   xchg   %ax,%ax

原因是GCC默認為-mcmodel=small ,其中靜態數據鏈接在地址空間的底部2G中。


請注意,字符串常量不會轉到數據段,但它們會在代碼段內,除非-fwritable-strings 此外,如果您想在內存中自由重定位目標代碼,您可能希望使用-fpic進行編譯以使代碼RIP相對而不是在任何地方放置64位地址。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM