GCC
Section: GNU Tools (1)
Updated: 2003/12/05
IndexReturn to Main Contents
?
?
NAME
gcc,g++-GNU 工程的 C 和 C++ 編譯器 (egcs-1.1.2) ?
總覽 (SYNOPSIS)
gcc[option|filename ]...
g++[option|filename ]...
警告 (WARNING)
本手冊頁內(nèi)容摘自 GNU C 編譯器的完整文檔 , 僅限于解釋選項的含義 .
除非有人自愿維護 , 否則本手冊頁不再更新 . 如果發(fā)現(xiàn)手冊頁和軟件之間有所矛盾 , 請查對 Info 文件 , Info 文件是權(quán)威文檔 .
如果我們發(fā)覺本手冊頁的內(nèi)容由于過時而導(dǎo)致明顯的混亂和抱怨時 , 我們就停止發(fā)布它 . 不可能有其他選擇 , 象更新 Info 文件同時更新 man 手冊 , 因為其他維護 GNU CC 的工作沒有留給我們時間做這個 . GNU 工程認為 man 手冊是過時產(chǎn)物 , 應(yīng)該把時間用到別的地方 .
如果需要完整和最新的文檔 , 請查閱 Info 文件 `gcc' 或 Using and Porting GNU CC (for version 2.0) ( 使用和移植 GNU CC 2.0) 手冊 . 二者均來自 Texinfo 原文件 gcc.texinfo.
描述 (DESCRIPTION)
C 和 C++ 編譯器是集成的 . 他們都要用四個步驟中的一個或多個處理輸入文件 : 預(yù)處理 (preprocessing), 編譯 (compilation), 匯編 (assembly) 和連接 (linking). 源文件后綴名標(biāo)識源文件的 語言 , 但是對編譯器來說 , 后綴名控制著缺省設(shè)定 :
- gcc
- 認為預(yù)處理后的文件 (.i) 是 C 文件 , 并且設(shè)定 C 形式的連接 .
- g++
- 認為預(yù)處理后的文件 (.i) 是 C++ 文件 , 并且設(shè)定 C++ 形式的連接 .
源文件后綴名指出語言種類以及后期的操作 :
?
.c C 源程序 ; 預(yù)處理 , 編譯 , 匯編 .C C++ 源程序 ; 預(yù)處理 , 編譯 , 匯編 .cc C++ 源程序 ; 預(yù)處理 , 編譯 , 匯編 .cxx C++ 源程序 ; 預(yù)處理 , 編譯 , 匯編 .m Objective-C 源程序 ; 預(yù)處理 , 編譯 , 匯編 .i 預(yù)處理后的 C 文件 ; 編譯 , 匯編 .ii 預(yù)處理后的 C++ 文件 ; 編譯 , 匯編 .s 匯編語言源程序 ; 匯編 .S 匯編語言源程序 ; 預(yù)處理 , 匯編 .h 預(yù)處理器文件 ; 通常不出現(xiàn)在命令行上
其他后綴名的文件被傳遞給連接器 (linker). 通常包括 :
?
.o 目標(biāo)文件 (Object file).a 歸檔庫文件 (Archive file)
除非使用了 -c, -S, 或 -E 選項 ( 或者編譯錯誤阻止了完整的過程 ), 否則連接總是 最后的步驟 . 在連接階段中 , 所有對應(yīng)于源程序的 .o 文件 , -l 庫文件 , 無法識別的文件名 ( 包括指定的 .o 目標(biāo)文件和 .a 庫文件 ) 按命令行中的順序傳遞給連接器 .
選項 (OPTIONS)
選項必須分立給出 : `-dr' 完全不同于 `-d -r '.
大多數(shù) `-f' 和 `-W' 選項有兩個相反的格式 : -fname 和 -fno- name ( 或 -W name 和 -Wno- name). 這里 只列舉不是默認選項的格式 .
下面是所有選項的摘要 , 按類型分組 , 解釋放在后面的章節(jié)中 .
- 總體選項 (Overall Option)
-
-c -S -E -o file -pipe -v -x language - 語言選項 (Language Option)
- -ansi -fall-virtual -fcond-mismatch -fdollars-in-identifiers -fenum-int-equiv -fexternal-templates -fno-asm -fno-builtin -fhosted -fno-hosted -ffreestanding -fno-freestanding -fno-strict-prototype -fsigned-bitfields -fsigned-char -fthis-is-variable -funsigned-bitfields -funsigned-char -fwritable-strings -traditional -traditional-cpp -trigraphs
- 警告選項 (Warning Option)
- -fsyntax-only -pedantic -pedantic-errors -w -W -Wall -Waggregate-return -Wcast-align -Wcast-qual -Wchar-subscript -Wcomment -Wconversion -Wenum-clash -Werror -Wformat -Wid-clash-len -Wimplicit -Wimplicit-int -Wimplicit-function-declaration -Winline -Wlong-long -Wmain -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Wno-import -Wparentheses -Wpointer-arith -Wredundant-decls -Wreturn-type -Wshadow -Wstrict-prototypes -Wswitch -Wtemplate-debugging -Wtraditional -Wtrigraphs -Wuninitialized -Wunused -Wwrite-strings
- 調(diào)試選項 (Debugging Option)
- -a -dletters -fpretend-float -g -glevel -gcoff -gxcoff -gxcoff+ -gdwarf -gdwarf+ -gstabs -gstabs+ -ggdb -p -pg -save-temps -print-file-name=library -print-libgcc-file-name -print-prog-name=program
- 優(yōu)化選項 (Optimization Option)
- -fcaller-saves -fcse-follow-jumps -fcse-skip-blocks -fdelayed-branch -felide-constructors -fexpensive-optimizations -ffast-math -ffloat-store -fforce-addr -fforce-mem -finline-functions -fkeep-inline-functions -fmemoize-lookups -fno-default-inline -fno-defer-pop -fno-function-cse -fno-inline -fno-peephole -fomit-frame-pointer -frerun-cse-after-loop -fschedule-insns -fschedule-insns2 -fstrength-reduce -fthread-jumps -funroll-all-loops -funroll-loops -O -O2 -O3
- 預(yù)處理器選項 (Preprocessor Option)
- -Aassertion -C -dD -dM -dN -Dmacro[=defn] -E -H -idirafter dir -include file -imacros file -iprefix file -iwithprefix dir -M -MD -MM -MMD -nostdinc -P -Umacro -undef
- 匯編器選項 (Assembler Option)
- -Wa,option
- 連接器選項 (Linker Option)
- -llibrary -nostartfiles -nostdlib -static -shared -symbolic -Xlinker?option -Wl,option -u symbol
- 目錄選項 (Directory Option)
- -Bprefix -Idir -I- -Ldir
- 目標(biāo)機選項 (Target Option)
- -b machine -V version
- 配置相關(guān)選項 (Configuration Dependent Option)
-
M680x0?
選項
-m68000 -m68020 -m68020-40 -m68030 -m68040 -m68881 -mbitfield -mc68000 -mc68020 -mfpa -mnobitfield -mrtd -mshort -msoft-floatVAX 選項
-mg -mgnu -munixSPARC 選項
-mepilogue -mfpu -mhard-float -mno-fpu -mno-epilogue -msoft-float -msparclite -mv8 -msupersparc -mcypressConvex 選項
-margcount -mc1 -mc2 -mnoargcountAMD29K 選項
-m29000 -m29050 -mbw -mdw -mkernel-registers -mlarge -mnbw -mnodw -msmall -mstack-check -muser-registersM88K 選項
-m88000 -m88100 -m88110 -mbig-pic -mcheck-zero-division -mhandle-large-shift -midentify-revision -mno-check-zero-division -mno-ocs-debug-info -mno-ocs-frame-position -mno-optimize-arg-area -mno-serialize-volatile -mno-underscores -mocs-debug-info -mocs-frame-position -moptimize-arg-area -mserialize-volatile -mshort-data-num -msvr3 -msvr4 -mtrap-large-shift -muse-div-instruction -mversion-03.00 -mwarn-passed-structsRS6000 選項
-mfp-in-toc -mno-fop-in-tocRT 選項
-mcall-lib-mul -mfp-arg-in-fpregs -mfp-arg-in-gregs -mfull-fp-blocks -mhc-struct-return -min-line-mul -mminimum-fp-blocks -mnohc-struct-returnMIPS 選項
-mcpu=cpu type -mips2 -mips3 -mint64 -mlong64 -mmips-as -mgas -mrnames -mno-rnames -mgpopt -mno-gpopt -mstats -mno-stats -mmemcpy -mno-memcpy -mno-mips-tfile -mmips-tfile -msoft-float -mhard-float -mabicalls -mno-abicalls -mhalf-pic -mno-half-pic -G num -nocppi386 選項
-m486 -mno-486 -msoft-float -mno-fp-ret-in-387HPPA 選項
-mpa-risc-1-0 -mpa-risc-1-1 -mkernel -mshared-libs -mno-shared-libs -mlong-calls -mdisable-fpregs -mdisable-indexing -mtrailing-coloni960 選項
-mcpu-type -mnumerics -msoft-float -mleaf-procedures -mno-leaf-procedures -mtail-call -mno-tail-call -mcomplex-addr -mno-complex-addr -mcode-align -mno-code-align -mic-compat -mic2.0-compat -mic3.0-compat -masm-compat -mintel-asm -mstrict-align -mno-strict-align -mold-align -mno-old-alignDEC Alpha 選項
-mfp-regs -mno-fp-regs -mno-soft-float -msoft-floatSystem V 選項
-G -Qy -Qn -YP,paths -Ym,dir - 代碼生成選項 (Code Generation Option)
-
-fcall-saved-reg -fcall-used-reg -ffixed-reg -finhibit-size-directive -fnonnull-objects -fno-common -fno-ident -fno-gnu-linker -fpcc-struct-return -fpic -fPIC -freg-struct-return -fshared-data -fshort-enums -fshort-double -fvolatile -fvolatile-global -fverbose-asm
?
總體選項 (Overall Option)
- -x language
- 明確指出后面輸入文件的語言為 language ( 而不是從文件名后綴得到的默認選擇 ). 這個選項應(yīng)用于后面 所有的輸入文件 , 直到遇著下一個 `-x' 選項 . language 的可選值有 `c', `objective-c', `c-header', `c++', `cpp-output', `assembler', 和 `assembler-with-cpp'.
- -x none
- 關(guān)閉任何對語種的明確說明 , 因此依據(jù)文件名后綴處理后面的文件 ( 就象是從未使用過 `-x' 選項 ).
如果只操作四個階段 ( 預(yù)處理 , 編譯 , 匯編 , 連接 ) 中的一部分 , 可以使用 `-x' 選項 ( 或文件名后綴 ) 告訴 gcc 從哪里開始 , 用 `-c', `-S', 或 `-E' 選項告訴 gcc 到 哪里結(jié)束 . 注意 , 某些選項組合 ( 例如 , `-x cpp-output -E') 使 gcc 不作任何事情 .
- -c
-
編譯或匯編源文件
,
但是不作連接
.
編譯器輸出對應(yīng)于源文件的目標(biāo)文件
.
缺省情況下 , GCC 通過用 `.o' 替換源文件名后綴 `.c', `.i', `.s', 等等 , 產(chǎn)生目標(biāo)文件名 . 可以使用 -o 選項選擇其他名字 .
GCC 忽略 -c 選項后面任何無法識別的輸入文件 ( 他們不需要編譯或匯編 ).
- -S
-
編譯后即停止
,
不進行匯編
.
對于每個輸入的非匯編語言文件
,
輸出文件是匯編語言文件
.
缺省情況下 , GCC 通過用 `.o' 替換源文件名后綴 `.c', `.i', 等等 , 產(chǎn)生 目標(biāo)文件名 . 可以使用 -o 選項選擇其他名字 .
GCC 忽略任何不需要編譯的輸入文件 .
- -E
-
預(yù)處理后即停止
,
不進行編譯
.
預(yù)處理后的代碼送往標(biāo)準(zhǔn)輸出
.
GCC 忽略任何不需要預(yù)處理的輸入文件 .
- -o file
-
指定輸出文件為
file.
該選項不在乎
GCC
產(chǎn)生什么輸出
,
無論是可執(zhí)行文件
,
目標(biāo)文件
,
匯編文件還是 預(yù)處理后的
C
代碼
.
由于只能指定一個輸出文件 , 因此編譯多個輸入文件時 , 使用 `-o' 選項沒有意義 , 除非輸出一個可執(zhí)行文件 .
如果沒有使用 `-o' 選項 , 默認的輸出結(jié)果是 : 可執(zhí)行文件為 `a.out', `source.suffix ' 的目標(biāo)文件是 `source.o', 匯編文件是 `source.s', 而預(yù)處理后的 C 源代碼送往標(biāo)準(zhǔn)輸出 .
- -v
- ( 在標(biāo)準(zhǔn)錯誤 ) 顯示執(zhí)行編譯階段的命令 . 同時顯示編譯器驅(qū)動程序 , 預(yù)處理器 , 編譯器的版本號 .
- -pipe
- 在編譯過程的不同階段間使用管道而非臨時文件進行通信 . 這個選項在某些系統(tǒng)上無法工作 , 因為那些系統(tǒng)的 匯編器不能從管道讀取數(shù)據(jù) . GNU 的匯編器沒有這個問題 .
?
語言選項 (LANGUAGE OPTIONS)
下列選項控制編譯器能夠接受的 C " 方言 ":
- -ansi
-
支持符合
ANSI
標(biāo)準(zhǔn)的
C
程序
.
這樣就會關(guān)閉 GNU C 中某些不兼容 ANSI C 的特性 , 例如 asm, inline 和 typeof 關(guān)鍵字 , 以及諸如 unix 和 vax 這些表明當(dāng)前系統(tǒng)類型的預(yù)定義宏 . 同時開啟 不受歡迎和極少使用的 ANSI trigraph 特性 , 以及禁止 `$' 成為標(biāo)識符的一部分 .
?
盡管使用了 `-ansi' 選項 , 下面這些可選的關(guān)鍵字 , __asm__, __extension__, __inline__ 和 __typeof__ 仍然有效 . 你當(dāng)然不會把 他們用在 ANSI C 程序中 , 但可以把他們放在頭文件里 , 因為編譯包含這些頭文件的程序時 , 可能會指定 `-ansi' 選項 . 另外一些預(yù)定義宏 , 如 __unix__ 和 __vax__, 無論有沒有使用 `-ansi' 選項 , 始終有效 .
?
使用 `-ansi' 選項不會自動拒絕編譯非 ANSI 程序 , 除非增加 `-pedantic' 選項作為 `-ansi' 選項的補充 .
?
使用 `-ansi' 選項的時候 , 預(yù)處理器會預(yù)定義一個 __STRICT_ANSI__ 宏 . 有些頭文件 關(guān)注此宏 , 以避免聲明某些函數(shù) , 或者避免定義某些宏 , 這些函數(shù)和宏不被 ANSI 標(biāo)準(zhǔn)調(diào)用 ; 這樣就不會干擾在其他地方 使用這些名字的程序了 .
?
- -fno-asm
- 不把 asm, inline 或 typeof 當(dāng)作關(guān)鍵字 , 因此這些詞可以用做標(biāo)識符 . 用 __asm__, __inline__ 和 __typeof__ 能夠替代他們 . `-ansi' 隱含聲明了 `-fno-asm'.
- -fno-builtin
-
不接受不是兩個下劃線開頭的內(nèi)建函數(shù)
(built-in function).
目前受影響的函數(shù)有
_exit, abort, abs, alloca, cos, exit, fabs, labs, memcmp, memcpy, sin, sqrt, strcmp, strcpy,
和
strlen.
`-ansi' 選項能夠阻止 alloca 和 _exit 成為內(nèi)建函數(shù) .
?
- -fhosted
- 按宿主環(huán)境編譯 ; 他隱含聲明了 `-fbuiltin' 選項 , 而且警告不正確的 main 函數(shù)聲明 .
- -ffreestanding
-
按獨立環(huán)境編譯
;
他隱含聲明了
`-fno-builtin'
選項
,
而且對
main
函數(shù)沒有特別要求
.
( 譯注 : 宿主環(huán)境 (hosted environment) 下所有的標(biāo)準(zhǔn)庫可用 , main 函數(shù)返回一個 int 值 , 典型例子是除了 內(nèi)核以外幾乎所有的程序 . 對應(yīng)的獨立環(huán)境 (freestanding environment) 不存在標(biāo)準(zhǔn)庫 , 程序入口也不一定是 main, 最明顯的例子就是操作系統(tǒng)內(nèi)核 . 詳情參考 gcc 網(wǎng)站最近的資料 )
?
- -fno-strict-prototype
-
對于沒有參數(shù)的函數(shù)聲明
,
例如
`int foo ();',
按
C
風(fēng)格處理
---
即不說明參數(shù)個數(shù)或類型
. (
僅針對
C++).
正常情況下
,
這樣的函數(shù)
foo
在
C++
中意味著參數(shù)為空
.
?
- -trigraphs
-
支持
ANSI C trigraphs. `-ansi'
選項隱含聲明了
`-trigraphs'.
?
- -traditional
-
試圖支持傳統(tǒng)
C
編譯器的某些方面
.
詳見
GNU C
手冊
,
我們已經(jīng)把細節(jié)清單從這里刪除
,
這樣當(dāng)內(nèi)容過時后
,
人們也不會 埋怨我們
.
除了一件事 : 對于 C++ 程序 ( 不是 C), `-traditional' 選項帶來一個附加效應(yīng) , 允許對 this 賦值 . 他和 `-fthis-is-variable' 選項的效果一樣 .
?
- -traditional-cpp
-
試圖支持傳統(tǒng)
C
預(yù)處理器的某些方面
.
特別是上面提到有關(guān)預(yù)處理器的內(nèi)容
,
但是不包括
`-traditional'
選項的其他效應(yīng)
.
?
- -fdollars-in-identifiers
-
允許在標(biāo)識符
(identifier)
中使用
`$'
字符
(
僅針對
C++).
你可以指定
`-fno-dollars-in-identifiers'
選項顯明禁止使用
`$'
符
. (GNU C++
在某些 目標(biāo)系統(tǒng)缺省允許
`$'
符
,
但不是所有系統(tǒng)
.)
?
- -fenum-int-equiv
-
允許
int
類型到枚舉類型
(enumeration)
的隱式轉(zhuǎn)換
(
僅限于
C++).
正常情況下
GNU C++
允許從
enum
到
int
的轉(zhuǎn)換
,
反之則不行
.
?
- -fexternal-templates
-
為模板聲明
(template declaration)
產(chǎn)生較小的代碼
(
僅限于
C++),
方法是對于每個模板函數(shù)
(template function),
只在定義他們的地方生成一個副本
.
想要成功使用這個選項
,
你必須在所有使用模板的 文件中
,
標(biāo)記
`#pragma implementation' (
定義
)
或
`#pragma interface' (
聲明
).
當(dāng)程序用 `-fexternal-templates' 編譯時 , 模板實例 (template instantiation) 全部是外部類型 . 你必須讓需要的實例在實現(xiàn)文件中出現(xiàn) . 可以通過 typedef 實現(xiàn)這一點 , 他引用所需的每個 實例 . 相對應(yīng)的 , 如果編譯時使用缺省選項 `-fno-external-templates', 所有模板實例明確的設(shè)為內(nèi)置 .
?
- -fall-virtual
-
所有可能的成員函數(shù)默認為虛函數(shù)
.
所有的成員函數(shù)
(
除了構(gòu)造子函數(shù)和
new
或
delete
成員操作符
)
視為所在類的虛函數(shù)
.
這不表明每次調(diào)用成員函數(shù)都將通過內(nèi)部虛函數(shù)表 . 有些情況下 , 編譯器能夠判斷出可以直接調(diào)用某個虛函數(shù) ; 這時就 直接調(diào)用 .
?
- -fcond-mismatch
-
允許條件表達式的第二和第三個參數(shù)的類型不匹配
.
這種表達式的值是
void.
?
- -fthis-is-variable
-
允許對
this
賦值
(
僅對
C++).
合并用戶自定義的自由存儲管理機制到
C++
后
,
使可賦值的
`this'
顯得不合時宜
.
因此
,
默認情況下
,
類成員函數(shù)內(nèi)部對
this
賦值是無效操作
.
然而為了 向后兼容
,
你可以通過
`-fthis-is-variable'
選項使這種操作有效
.
?
- -funsigned-char
-
把
char
定義為無符號類型
,
如同
unsigned char.
各種機器都有自己缺省的 char 類型 . 既可能是 unsigned char 也可能是 signed char .
理想情況下 , 當(dāng)依賴于數(shù)據(jù)的符號性時 , 一個可移植程序總是應(yīng)該使用 signed char 或 unsigned char. 但是許多程序已經(jīng)寫成只用簡單的 char, 并且期待這是有符號數(shù) ( 或者無符號數(shù) , 具體情況取決于 編寫程序的目標(biāo)機器 ). 這個選項 , 和它的反義選項 , 使那樣的程序工作在對應(yīng)的默認值上 .
char 的類型始終應(yīng)該明確定義為 signed char 或 unsigned char, 即使 它表現(xiàn)的和其中之一完全一樣 .
?
- -fsigned-char
-
把
char
定義為有符號類型
,
如同
signed char.
這個選項等同于 `-fno-unsigned-char', 他是 the negative form of `-funsigned-char' 的相反選項 . 同樣 , `-fno-signed-char' 等價于 `-funsigned-char'.
?
- -fsigned-bitfields
- -funsigned-bitfields
- -fno-signed-bitfields
- -fno-unsigned-bitfields
-
如果沒有明確聲明
`signed'
或
`unsigned'
修飾符
,
這些選項用來定義有符號位域
(bitfield)
或無符號位域
.
缺省情況下
,
位域是有符號的
,
因為他們繼承的基本整數(shù)類型
,
如
int,
是 有符號數(shù)
.
然而 , 如果指定了 `-traditional' 選項 , 位域永遠是無符號數(shù) .
?
- -fwritable-strings
-
把字符串常量存儲到可寫數(shù)據(jù)段
,
而且不做特別對待
.
這是為了兼容一些老程序
,
他們假設(shè)字符串常量是可寫的
. `-traditional'
選項也有相同效果
.
篡改字符串常量是一個非常糟糕的想法 ; `` 常量 '' 就應(yīng)該是常量 .
?
預(yù)處理器選項 (Preprocessor Option)
下列選項針對 C 預(yù)處理器 , 預(yù)處理器用在正式編譯以前 , 對 C 源文件進行某種處理 .
如果指定了 `-E' 選項 , GCC 只進行預(yù)處理工作 . 下面的某些選項必須和 `-E' 選項一起才 有意義 , 因為他們的輸出結(jié)果不能用于編譯 .
?
- -include file
-
在處理常規(guī)輸入文件之前
,
首先處理文件
file,
其結(jié)果是
,
文件
file
的內(nèi)容先得到編譯
.
命令行上任何
`-D'
和
`-U'
選項永遠在
`-include file'
之前處理
,
無論他們在命令行上的順序如何
.
然而
`-include'
和
`-imacros'
選項按書寫順序處理
.
?
- -imacros file
-
在處理常規(guī)輸入文件之前
,
首先處理文件
file,
但是忽略輸出結(jié)果
.
由于丟棄了文件
file
的 輸出內(nèi)容
, `-imacros file'
選項的唯一效果就是使文件
file
中的宏定義生效
,
可以用于其他輸入文件
.
在處理
`-imacrosfile'
選項之前
,
預(yù)處理器首先處理
`-D'
和
`-U'
選項
,
并不在乎他們在命令行上的順序
.
然而
`-include'
和
`-imacros'
選項按書寫順序處理
.
?
- -idirafter dir
-
把目錄
dir
添加到第二包含路徑中
.
如果某個頭文件在主包含路徑
(
用
`-I'
添加的路徑
)
中沒有 找到
,
預(yù)處理器就搜索第二包含路徑
.
?
- -iprefix prefix
-
指定
prefix
作為后續(xù)
`-iwithprefix'
選項的前綴
.
?
- -iwithprefix dir
-
把目錄添加到第二包含路徑中
.
目錄名由
prefix
和
dir
合并而成
,
這里
prefix
被先前的
`-iprefix'
選項指定
.
?
- -nostdinc
-
不要在標(biāo)準(zhǔn)系統(tǒng)目錄中尋找頭文件
.
只搜索
`-I'
選項指定的目錄
(
以及當(dāng)前目錄
,
如果合適
).
結(jié)合使用 `-nostdinc' 和 `-I-' 選項.\\
內(nèi)嵌匯編語法如下:
?????? __asm__(匯編語句模板: 輸出部分: 輸入部分: 破壞描述部分)
共四個部分:匯編語句模板,輸出部分,輸入部分,破壞描述部分,各部分使用“:”格開,匯編語句模板必不可少,其他三部分可選,如果使用了后面的部分,而前面部分為空,也需要用“:”格開,相應(yīng)部分內(nèi)容為空。例如:
???????????? __asm__ __volatile__("cli": : :"memory")
1、匯編語句模板
????匯編語句模板由匯編語句序列組成,語句之間使用“;”、“\n”或“\n\t”分開。指令中的操作數(shù)可以使用占位符引用C語言變量,操作數(shù)占位符最多10個,名稱如下:%0,%1,…,%9。指令中使用占位符表示的操作數(shù),總被視為long型(4個字節(jié)),但對其施加的操作根據(jù)指令可以是字或者字節(jié),當(dāng)把操作數(shù)當(dāng)作字或者字節(jié)使用時,默認為低字或者低字節(jié)。對字節(jié)操作可以顯式的指明是低字節(jié)還是次字節(jié)。方法是在%和序號之間插入一個字母,“b”代表低字節(jié),“h”代表高字節(jié),例如:%h1。
2、輸出部分
????輸出部分描述輸出操作數(shù),不同的操作數(shù)描述符之間用逗號格開,每個操作數(shù)描述符由限定字符串和C 語言變量組成。每個輸出操作數(shù)的限定字符串必須包含“=”表示他是一個輸出操作數(shù)。
例:
??????????__asm__ __volatile__("pushfl ; popl %0 ; cli":"=g" (x) )
描述符字符串表示對該變量的限制條件,這樣GCC 就可以根據(jù)這些條件決定如何分配寄存器,如何產(chǎn)生必要的代碼處理指令操作數(shù)與C表達式或C變量之間的聯(lián)系。
3、輸入部分
輸入部分描述輸入操作數(shù),不同的操作數(shù)描述符之間使用逗號格開,每個操作數(shù)描述符由限定字符串和C語言表達式或者C語言變量組成。
例1 :
????????????__asm__ __volatile__ ("lidt %0" : : "m" (real_mode_idt));
例二(bitops.h):
Static __inline__ void __set_bit(int nr, volatile void * addr)
{
????????__asm__(
???????????????????????? "btsl %1,%0"
????????????????????????:"=m" (ADDR)
????????????????????????:"Ir" (nr));
}
后例功能是將(*addr)的第nr位設(shè)為1。第一個占位符%0與C 語言變量ADDR對應(yīng),第二個占位符%1與C語言變量nr對應(yīng)。因此上面的匯編語句代碼與下面的偽代碼等價:btsl nr, ADDR,該指令的兩個操作數(shù)不能全是內(nèi)存變量,因此將nr的限定字符串指定為“Ir”,將nr 與立即數(shù)或者寄存器相關(guān)聯(lián),這樣兩個操作數(shù)中只有ADDR為內(nèi)存變量。
4、限制字符
?? 4.1、限制字符列表
?? 限制字符有很多種,有些是與特定體系結(jié)構(gòu)相關(guān),此處僅列出常用的限定字符和i386中可能用到的一些常用的限定符。它們的作用是指示編譯器如何處理其后的C語言變量與指令操作數(shù)之間的關(guān)系。
?? 分類????????????限定符????????????????????描述
??通用寄存器?????? “a”?????????????? 將輸入變量放入eax
??????????????????????????????????????????????這里有一個問題:假設(shè)eax已經(jīng)被使用,那怎么辦?
???????????????????????????????? 其實很簡單:因為GCC 知道eax 已經(jīng)被使用,它在這段匯編代碼
???????????????????????????????? 的起始處插入一條語句pushl %eax,將eax 內(nèi)容保存到堆棧,然
???????????????????????????????? 后在這段代碼結(jié)束處再增加一條語句popl %eax,恢復(fù)eax的內(nèi)容
?????????????????? “b”?????????????? 將輸入變量放入ebx
???????????????????????????? “c”?????????????? 將輸入變量放入ecx
????????????????????????????“d”????????????????將輸入變量放入edx
???????????????????????????? “s”?????????????? 將輸入變量放入esi
????????????????????????????“d”?????????????? 將輸入變量放入edi
???????????????????????????? “q”??????????????將輸入變量放入eax,ebx,ecx,edx中的一個
?????????????????? “r”?????????????? 將輸入變量放入通用寄存器,也就是eax,ebx,ecx,
????????????????????????????????????????edx,esi,edi中的一個
????????????????????“A”??????????????把eax和edx合成一個64 位的寄存器(use long longs)
?????? 內(nèi)存????????????“m”???????????? 內(nèi)存變量
???????????????????? “o”???????????? 操作數(shù)為內(nèi)存變量,但是其尋址方式是偏移量類型,
?????????????????????????????????????? 也即是基址尋址,或者是基址加變址尋址
???????????????????? “V”???????????? 操作數(shù)為內(nèi)存變量,但尋址方式不是偏移量類型
???????????????????? “ ”???????????? 操作數(shù)為內(nèi)存變量,但尋址方式為自動增量
???????????????????? “p”???????????? 操作數(shù)是一個合法的內(nèi)存地址(指針)
???? 寄存器或內(nèi)存????“g”???????????? 將輸入變量放入eax,ebx,ecx,edx中的一個
?????????????????????????????????????? 或者作為內(nèi)存變量
??????????????????????“X”????????????操作數(shù)可以是任何類型
???? 立即數(shù)
???????????????????? “I”???????????? 0-31之間的立即數(shù)(用于32位移位指令)
??????????????????????“J”????????????0-63之間的立即數(shù)(用于64位移位指令)
???????????????????? “N”???????????? 0-255之間的立即數(shù)(用于out指令)
???????????????????? “i”???????????? 立即數(shù)??
???????????????????? “n”????????????立即數(shù),有些系統(tǒng)不支持除字以外的立即數(shù),
?????????????????????????????????????? 這些系統(tǒng)應(yīng)該使用“n”而不是“i”
???? 匹配????????????“ 0 ”,???????? 表示用它限制的操作數(shù)與某個指定的操作數(shù)匹配,
???????????????????? “1” ...?????????????? 也即該操作數(shù)就是指定的那個操作數(shù),例如“0”
??????????????????????“9”????????????去描述“%1”操作數(shù),那么“%1”引用的其實就
?????????????????????????????????????? 是“%0”操作數(shù),注意作為限定符字母的0-9 與
?????????????????????????????????????? 指令中的“%0”-“%9”的區(qū)別,前者描述操作數(shù),
?????????????????????????????????????? 后者代表操作數(shù)。
?????????????????????? &???????????????????? 該輸出操作數(shù)不能使用過和輸入操作數(shù)相同的寄存器
????操作數(shù)類型????????“=”??????????操作數(shù)在指令中是只寫的(輸出操作數(shù))??
?????????????????????? “+”??????????操作數(shù)在指令中是讀寫類型的(輸入輸出操作數(shù))
???? 浮點數(shù)????????????“f”??????????浮點寄存器
??????????????????????“t”?????????? 第一個浮點寄存器
??????????????????????“u”??????????第二個浮點寄存器
??????????????????????“G”??????????標(biāo)準(zhǔn)的80387浮點常數(shù)
?????????????????????? %?????????????????? 該操作數(shù)可以和下一個操作數(shù)交換位置
?????????????????????????????????????? 例如addl的兩個操作數(shù)可以交換順序
??????????????????????????????????????(當(dāng)然兩個操作數(shù)都不能是立即數(shù))
?????????????????????? #?????????????????? 部分注釋,從該字符到其后的逗號之間所有字母被忽略
?????????????????????? *???????????????????? 表示如果選用寄存器,則其后的字母被忽略
5、破壞描述部分
?? 破壞描述符用于通知編譯器我們使用了哪些寄存器或內(nèi)存,由逗號格開的字符串組成,每個字符串描述一種情況,一般是寄存器名;除寄存器外還有“memory”。例如:“%eax”,“%ebx”,“memory”等。
凡是有該標(biāo)志的文章,都是該blog博主Caoer(草兒)原創(chuàng),凡是索引、收藏
、轉(zhuǎn)載請注明來處和原文作者。非常感謝。