内核bug.h以及GCC内联汇编的学习

所有的学习的内容都在注释当中,我的学习过程是,看到这个代码段之后,将其中需要的只是去大体的学习一遍。争取能够做到理解整体的部分。

下面展示出我的学习的代码:

#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汇编,发现有很多的不同。通过看一篇文章,对其进行了一个大体的总结,还是比较有价值的。

AT&T与intel汇编的比较

时间: 2024-10-12 03:30:10

内核bug.h以及GCC内联汇编的学习的相关文章

最牛X的GCC 内联汇编

导读 正如大家知道的,在C语言中插入汇编语言,其是Linux中使用的基本汇编程序语法.本文将讲解 GCC 提供的内联汇编特性的用途和用法.对于阅读这篇文章,这里只有两个前提要求,很明显,就是 x86 汇编语言和 C 语言的基本认识. 1. 简介 1.1 版权许可 Copyright (C) 2003 Sandeep S. 本文档自由共享:你可以重新发布它,并且/或者在遵循自由软件基金会发布的 GNU 通用公共许可证下修改它:也可以是该许可证的版本 2 或者(按照你的需求)更晚的版本. 发布这篇文

GCC内联汇编入门

原文为GCC-Inline-Assembly-HOWTO,在google上可以找到原文,欢迎指出翻译错误. 中文版说明 由于译者水平有限,故译文出错之处,还请见谅.C语言的关键字不译,一些单词或词组(如colbber等)由于恐怕译后词不达意,故并不翻译,由下面的单词表代为解释,敬请见谅. 英文原文中的单词和词组: operand:操作数,可以是寄存器,内存,立即数. volatile:易挥发的,是C语言的关键字. constraint: 约束. register: 本文指CPU寄存器. asm:

[翻译] GCC 内联汇编 HOWTO

GCC 内联汇编 HOWTO v0.1, 01 March 2003. * * * 本 HOWTO 文档将讲解 GCC 提供的内联汇编特性的用途和用法.对于阅读这篇文章,这里只有两个前提要求,很明显,就是 x86 汇编语言和 C 语言的基本认识. [TOC] 原文链接与说明 http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html 本翻译文档原文选题自 Linux中国 ,翻译文档版权归属 Linux中国 所有 1. 简介 1.

【转贴】GCC内联汇编基础

原文作者 Sandeep.S英文原文 [https://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html] 本文将介绍GCC编译环境下,在C语言代码中嵌入汇编代码的基本方法.阅读本文需要您具备80X86汇编语言和C语言的基础知识.为了使中文描述更加清楚自然,翻译过程中加入了稍许解释和意译部分. 简介 版权/反馈/勘误/感谢等信息.[^ 1][^ 1]:这里信息价值不大,没有翻译.具体参加原文:https://www.ibiblio.

Android漫游记(5)---ARM GCC 内联汇编烹饪书(附实例分析)

原文链接(点击打开链接) 关于本文档 GNU C编译器针对ARM RISC处理器,提供了内联汇编支持.利用这一非常酷炫的特性,我们可以用来优化软件代码中的关键部分,或者可以使用针对特定处理的汇编处理指令. 本文假定,你已经熟悉ARM汇编语言.本文不是一篇ARM汇编教程,也不是C语言教程. GCC汇编声明 让我们从一个简单的例子开始.下面的一条ARM汇编指令,你可以添加到C源码中. /* NOP example-空操作 */ asm("mov r0,r0"); 上面的指令,讲r0寄存器的

操作系统学习之GCC内联汇编

GCC内联汇编(INLINE ASSEMBLY) 什么是内联汇编(Inline assembly)? 1.这是GCC对C语言的扩张,就是在C代码里面去写汇编代码 2.可以直接在C的语句中插入汇编指令 有何用处? 1.C语言不足以完成所有CPU的指令, 特别是有一些特权指令,比如加载gdt表(Global Descriptor Table 全局描述符表),从而使用汇编代码来完成 2.用汇编在C语言中手动优化,特别是在操作系统当中,使用汇编对操作系统的掌控更为精准,更加准确. 如何工作? 1.用给定

GCC 内联汇编约束字符&quot;m&quot;的用法

首先是这么一段代码(例一): #include<stdio.h> void main() {     char c;     //int tmp;     char *s="abcdefg";     asm("movb %1,%0\n\t"     :"=d"(c)     :"m"(*s));     printf("out:%c\n",c); } 这段代码运行后会出现什么结果呢?很显然,是

GCC内联汇编

GCC,linux的GNU C编译器使用AT&T/UNIX汇编语法. (一):AT&T汇编和intel汇编的不同 1:前缀 在intel语法中,寄存器和立即数都没有前缀,而在AT&T中,寄存器使用前缀"%",而立即数前面使用前缀"$"; 在intel语法中,十六进制和二进制立即数后面缀以"h"和"b",但在AT&T语法中,在前面缀以"0x", 2:操作数的方向不同 AT&am

VC内联汇编和GCC内联汇编的语法区别

VC: #include <stdio.h> main(){ int a = 1; int b = 2; int c; __asm{ mov eax,a mov ebx,b mov ecx,1h add eax,ebx mov c,ecx } printf("%x\n", c); } GCC: #include <stdio.h> main(){ int a = 1; int b = 2; int c; asm( "add %2,%0" //