所有的学习的内容都在注释当中,我的学习过程是,看到这个代码段之后,将其中需要的只是去大体的学习一遍。争取能够做到理解整体的部分。
下面展示出我的学习的代码:
#ifndef _I386_BUG_H
#define _I386_BUG_H
/*
* Tell the user there is some problem.
* 告诉用户出现了一些问题
* The offending file and line are encoded after the "officially
* undefined" opcode for parsing in the trap handler.
*
* 有问题的文件和行被编码在“官方未定义”操作码之后,为了能够在陷阱
* 处理程序中被解析。
*/
/**
* 1:__asm__:gcc内联汇编的方式
* gcc内联汇编的通用方式是:
* 内嵌汇编语法: __asm__(汇编语句模板: 输出部分: 输入部分: 破坏描述部分)
* 共四个部分所组成:汇编语句模板,输出部分,输入部分,破坏描述部分,
* 各部分使用“:”格开,汇编语句模板必不可少, 其他三部分可选,
* 如果使用了后面的部分,而前面部分为空,也需要用“:”格开,相应部分内容为空
*
* 2:ud2指令是一种让CPU产生invalid opcode exception的软件指令,
* 内核发现CPU出现这个异常,会立即停止运行
* 3:__volatile__告诉编译器,现在所写的没一条指令都是不可变的,包括顺序,
* 如果不带__volatile__的话,如果在使用gcc编译的过程中,使用了优化选型-O,
* 则编译器就会根据自己的优化规则对代码进行优化
* 4:下面带上内联之后可能看的不太清楚,这样,光看汇编指令:
* ud2 ;
* .word %c0 ;
* .long %c1 ;
* : : "i" (__LINE__),"i" (__FILE__) ;
*
* 从上面的代码上可以看出:
* ud2;指令,使CPU停止运行
* .word %c0;指定占位符%c0位置是一个字
* .long %c1;指定占位符%c1位置是一个long整数
* : : ;省略中间的输出部分
* "i" (__LINE__),"i" (__FILE__)分别用(__LINE__)和(__FILE__)
* 去替换占位符%c0,%c1,其中"i"指明使用一个整数类型的立即数
*
* 5:下面是一些寄存器约束的缩写
* r:I/O,表示使用一个通用寄存器,由GCC在%eax/%ax/%al、%ebx/%bx/%bl、%ecx/%cx/%cl、%edx/%dx/%dl中选取一个GCC认为是合适的;
* q:I/O,表示使用一个通用寄存器,与r的意义相同;
* g:I/O,表示使用寄存器或内存地址;
* m:I/O,表示使用内存地址;
* a:I/O,表示使用%eax/%ax/%al;
* b:I/O,表示使用%ebx/%bx/%bl;
* c:I/O,表示使用%ecx/%cx/%cl;
* d:I/O,表示使用%edx/%dx/%dl;
* D:I/O,表示使用%edi/%di;
* S:I/O,表示使用%esi/%si;
* f:I/O,表示使用浮点寄存器;
* t:I/O,表示使用第一个浮点寄存器;
* u:I/O,表示使用第二个浮点寄存器;
* A:I/O,表示把%eax与%edx组合成一个64位的整数值;
* o:I/O,表示使用一个内存位置的偏移量;
* V:I/O,表示仅仅使用一个直接内存位置;
* i:I/O,表示使用一个整数类型的立即数;
* n:I/O,表示使用一个带有已知整数值的立即数;
* F:I/O,表示使用一个浮点类型的立即数;
*
*
*
*/
#ifdef CONFIG_BUG
#define HAVE_ARCH_BUG
#ifdef CONFIG_DEBUG_BUGVERBOSE
#define BUG() \
__asm__ __volatile__( "ud2\n" "\t.word %c0\n" "\t.long %c1\n" : : "i" (__LINE__), "i" (__FILE__))
#else
#define BUG() __asm__ __volatile__("ud2\n") //直接使CPU停止运行
#endif
#endif
#include <asm-generic/bug.h>
#endif
在GCC内联汇编的过程中,看到GCC只支持AT&T汇编语言,其中了解到一些有关于AT&T汇编语言的特性。由于之前学习过X86汇编,发现有很多的不同。通过看一篇文章,对其进行了一个大体的总结,还是比较有价值的。
时间: 2024-10-12 03:30:10