UNIX/Linux 中的預設字大小
我正在檢查我的 C 程序的預處理輸出,碰巧查看了標頭檔
wordsize.h
它位於
/usr/include/i386-linux-gnu/bits/wordsize.h
該文件僅包含一個宏
#define __WORDSIZE 32
我的問題是,字大小是由安裝的編譯器決定的,還是與我安裝的作業系統(32 位或 64 位)有關,還是與我的硬體配置有關機器。
我是 Linux 下開發的新手。
通常
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
了解此定義的用法。對於交叉編譯,請查看multilib(SO 上的 32 位連結)並蒐索 tha web。
檢查您的 GCC 是用哪些標誌建構的:
gcc -v
至於大小,它們通常與中央處理單元密切相關,並且相關——例如記憶體地址的最大大小、CPU 寄存器的大小等。
快速瀏覽一下,您不需要了解太多,但根據*您所在的位置,*它可以提供一些見解:
如果您使用
gcc
和編譯-S
標誌,您還可以查看彙編指令。在這裡,有點令人困惑,例如在 32 位機器上,一個 word 是 16 位,long 是 32 位。(__WORDSIZE
)因此,例如
movl $123, %eax
意味著將 long(32 位 -__WORDSIZE
)移動123
到eax
register,並且movw
意味著移動字(16 位)。這是命名約定,並且只能說這
WORDSIZE
可能意味著不止一件事。您還可以遇到他們定義的程式碼,例如#define WORD_SIZE 16
因為這一切都取決於上下文。如果您從源的字長為 16 位的文件或流中讀取數據,這很自然。只是要指出,
__WORDSIZE
在程式碼中讀取時並不總是假設字長意味著。使用者定義的範例
WORD_SIZE
不會影響生成的機器程式碼中的指令集。對於一般的 GCC,我會推薦這本書。(不幸的是它有點舊了——但還沒有找到類似的易於閱讀的最新書籍。(不是我看起來那麼難。)它簡短、簡潔、甜美。如果你只記住事情可能會發生變化,例如添加的功能等,但它提供了很好的介紹。)它在編譯時對各個方面進行了快速而漂亮的介紹。看第 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 Real Mode。
簡而言之,BIOS 會進行硬體測試,然後將引導磁碟的前 512 個字節載入到記憶體中,並將控制權留給從 address 開始的程式碼
0
。該程式碼依次定位下一階段的文件所在的位置,將它們載入到記憶體中並繼續執行,最終進入 具有正常32 位模式的保護模式。