- 論壇徽章:
- 0
|
albcamus 說得沒錯(cuò),
查了一下手冊(cè), UD2是一種讓CPU產(chǎn)生invalid opcode exception的軟件指令. 內(nèi)核發(fā)現(xiàn)CPU出現(xiàn)這個(gè)異常, 會(huì)立即停止運(yùn)行.
'c' 在gcc中, 叫做operand code, c只能用在常量變量(就是constraint是'i')和條件判斷指令中. 作用是將這個(gè)常量值打印在指令中.
這段代碼:
- #define BUG() \
- do { \
- asm volatile("1:\tud2\n" \
- ".pushsection __bug_table,\"a\"\n" \
- "2:\t.long 1b, %c0\n" \
- "\t.word %c1, 0\n" \
- "\t.org 2b+%c2\n" \
- ".popsection" \
- : : "i" (__FILE__), "i" (__LINE__), \
- "i" (sizeof(struct bug_entry))); \
- for(;;) ; \
- } while(0)
復(fù)制代碼
編譯后的代碼為:
- .LC0:
- .string "asm.c"
- .text
- .....
- #APP
- 1: ud2
- .pushsection __bug_table,"a"
- 2: .long 1b, .LC0
- .word 18, 0
- .org 2b+4
- .popsection
- #NO_APP
復(fù)制代碼
其實(shí)除了ud2這條指令, 其他都是assembler directives.
如果沒有'c'這個(gè)operand code, 產(chǎn)生的指令是:
- .LC0:
- .string "asm.c"
- .text
- #APP
- 1: ud2
- .pushsection __bug_table,"a"
- 2: .long 1b, $.LC0
- .word $18, 0
- .org 2b+$4
- .popsection
- #NO_APP
復(fù)制代碼
這段代碼對(duì)于assembler directives(GAS的輸入)來說, 可能是不能正常工作的.
i386的operand code可以在gcc源代碼的gcc/config/i386.c中查詢到, 我也是很久以前移植過一種CPU ARCH才記得有這么個(gè)東西.
L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
C -- print opcode suffix for set/cmov insn.
c -- like C, but print reversed condition
F,f -- likewise, but for floating-point.
O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
otherwise nothing
R -- print the prefix for register names.
z -- print the opcode suffix for the size of the current operand.
* -- print a star (in certain assembler syntax)
A -- print an absolute memory reference.
w -- print the operand as if it's a "word" (HImode) even if it isn't.
s -- print a shift double count, followed by the assemblers argument
delimiter.
b -- print the QImode name of the register for the indicated operand.
%b0 would print %al if operands[0] is reg 0.
w -- likewise, print the HImode name of the register.
k -- likewise, print the SImode name of the register.
q -- likewise, print the DImode name of the register.
h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
y -- print "st(0)" instead of "st" as a register.
D -- print condition for SSE cmp instruction.
P -- if PIC, print an @PLT suffix.
X -- don't print any sort of PIC '@' suffix for a symbol.
& -- print some in-use local-dynamic symbol name.
ps. 較新的內(nèi)核代碼都已經(jīng)將BUG()的實(shí)現(xiàn)做了一些修改, 改成了我上面提到的那種, 這可以讓出錯(cuò)的指令直接在棧頂, 便于調(diào)試. |
|