我正在檢查 C 程式的預處理輸出,碰巧查看了頭文件wordsize.h
它位於
/usr/include/i386-linux-gnu/bits/wordsize.h
該文件僅包含一個宏
#define __WORDSIZE 32
我的問題是,字長是由安裝的編譯器決定的,還是與我安裝的作業系統(32 位元或 64 位元)有關,還是與我的硬體配置有關?
我是 Linux 下的開發新手。
答案1
一般來說wordsize
編譯時根據目標架構決定。您的編譯器通常會wordsize
針對目前系統進行編譯。
使用gcc
(除其他外)您還可以透過使用各種標誌來調整它。例如,在 64 位元主機上,您可以編譯32位機器,或力量32 位元字。
-m32 # int, long and pointer to 32 bits, generates code for i386.
-m64 # int, long and pointer to 64 bits, generates code for x86-64.
-mx32 # int, long and pointer to 32 bits, generates code for x86-64.
您還應該查看limits.h
並inttypes.h
了解此定義的用法。
對於交叉編譯檢查多庫(SO 上的 32 位元鏈接)並蒐索網路。
檢查您的 GCC 是使用哪些標誌建構的:
gcc -v
至於大小,它們通常與中央處理器密切相關——例如記憶體位址的最大大小、CPU暫存器的大小等。
為了快速瀏覽,您不需要了解太多,但取決於你在哪裡它可以提供一些見解:
如果您使用gcc
該標誌並進行編譯,-S
您也可以查看組裝說明。這裡,有點令人困惑,例如在 32 位元機器上,一個字是 16 位元,而長度是 32 位元。 ( __WORDSIZE
)
因此,egmovl $123, %eax
表示長移(32 位元 - __WORDSIZE
)123
eax
註冊、 和movw
表示移動字(16 位元)。
這是命名約定,而且只是說這WORDSIZE
可能意味著不只一件事。您也可以遇到程式碼,例如,它們定義了類似的內容
#define WORD_SIZE 16
因為這一切都取決於上下文。如果您從來源字大小為 16 位元的檔案或流中讀取數據,這是很自然的。只是要指出,__WORDSIZE
在程式碼中讀取時不要總是假設字大小。
使用者定義的範例WORD_SIZE
不會影響產生的機器碼中的指令集。對於海灣合作委員會來說,我建議這本書。(不幸的是,它有點舊了——但還沒有找到一本類似的、易於閱讀的最新書。(並不是說我看起來那麼努力。)它簡短、簡潔、甜蜜。如果你只記住這一點事情可能會發生變化,例如添加功能等,但它仍然提供了很好的介紹。
它對編譯時的各個方面進行了快速而精彩的介紹。看著第11章一個很好的編譯鏈解釋。
我不知道 GCC 中有任何編譯 16 位元的選項。一種方法是用彙編語言編寫,.code16
以指示程式碼應該是 16 位元。
例子:
.file "hello.s"
.text
.code16 /* Tel GAS to use 16-bit instructions. */
.globl start, _start
start:
_start:
movb $0x48, %al
...
例如,引導程式(例如 GRUB 和 LILO)需要它來儲存MBR
硬碟上的程式碼。
原因是,當您的電腦啟動時,CPU 處於特殊模式,其中沒有 32 位元指令,但最多有 16 位元指令(AKA) 實模式。
簡而言之,BIOS 會進行硬體測試,然後將啟動磁碟的前 512 位元組載入到記憶體中,並將控制權留給從位址開始的程式碼0
。程式碼依序定位下一階段檔案所在的位置,將它們載入到記憶體中並繼續執行,最後輸入
保護模式你在哪裡普通的32 位元模式。
答案2
這是我的:
% cat /usr/include/bits/wordsize.h
/* Determine the wordsize from the preprocessor defines. */
#if defined __x86_64__
# define __WORDSIZE 64
# define __WORDSIZE_COMPAT32 1
#else
# define __WORDSIZE 32
#endif
所以它是由wordsize.h
編譯器附帶的 決定的。但聰明的人會選擇合適的尺寸。
答案3
您應該能夠在編譯時選擇預設字長,通常透過使用-m32
或-m64
選項之一。
/usr/include/i386-linux-gnu/bits/wordsize.h
設計用於編譯 32 位元應用程式時使用。
應該有一個/usr/include/x86_64-linux-gnu/bits/wordsize.h
包含 64 位元__WORDSIZE
定義的檔案。
此更改是在 Ubuntu 11.4 中引入的:https://wiki.ubuntu.com/MultiarchSpec
如果-m64
失敗,您可能擁有 32 位元發行版。uname -m
會告訴你的。
雖然可以在 32 位元系統上交叉編譯 64 位元二進位檔案,但這會很不方便,因為您沒有任何簡單的方法來運行它們。
如果您的 CPU 是 64 位元型號(使用 進行檢查lscpu
),您可能需要安裝 64 位元發行版以便輕鬆建立多架構套件。