首页 > 学技术 > 技术网文 > Linux > 正文

[保留] ud2是什么指令?


来源 chinaunix.net 酷勤网整理

#define BUG() \
 __asm__ __volatile__( "ud2\n" \
"\t.word %c0\n" \
"\t.long %c1\n" \
 : : "i" (__LINE__), "i" (__FILE__))


ud2是什么指令?机器码好像是0f 0b ?
BUG()能造成系统停机么?

%0、%1是占位符号,那么前面的修饰符'c'是什么含意?(%c0、%c1)
除了'c'还有哪些修饰符?在哪里可以查到这些修饰符的信息?



 albcamus 回复于:2007-06-21 10:06:38

undefined, 故意让CPU出错的 -- 记得是这样,FIXME


 
xiaozhaoz 回复于:2007-06-22 09:46:25

albcamus 说得没错, 

查了一下手册, UD2是一种让CPU产生invalid opcode exception的软件指令.  内核发现CPU出现这个异常, 会立即停止运行.

'c' 在gcc中, 叫做operand code, c只能用在常量变量(就是constraint是'i')和条件判断指令中. 作用是将这个常量值打印在指令中. 
这段代码:

#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)

编译后的代码为:

.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

其实除了ud2这条指令, 其他都是assembler directives. 

如果没有'c'这个operand code, 产生的指令是:

.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

这段代码对于assembler directives(GAS的输入)来说, 可能是不能正常工作的.

i386的operand code可以在gcc源代码的gcc/config/i386.c中查询到, 我也是很久以前移植过一种CPU ARCH才记得有这么个东西.
   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. 较新的内核代码都已经将BUG()的实现做了一些修改, 改成了我上面提到的那种, 这可以让出错的指令直接在栈顶, 便于调试.




原文链接:http://linux.chinaunix.net/bbs/viewthread.php?tid=901519
转载请注明作者名及原文出处



收藏本页到: