1 / 6
文档名称:

嵌入C代码中的386汇编语言程序段.docx

格式:docx   大小:25KB   页数:6页
下载后只包含 1 个 DOCX 格式的文档,没有任何的图纸或源代码,查看文件列表

如果您已付费下载过本站文档,您可以点这里二次下载

分享

预览

嵌入C代码中的386汇编语言程序段.docx

上传人:mh900965 2017/6/25 文件大小:25 KB

下载得到文件列表

嵌入C代码中的386汇编语言程序段.docx

文档介绍

文档介绍:嵌入C代码中的386汇编语言程序段
当需要在C语言的程序中嵌入一段汇编语言程序段时,提供的“asm”语句功能。例如,下面这么一行代码:
#define __SLOW_DOWN_IO __asm__ __volatile__(“outb %al, $0x80”)
这里,暂时忽略在asm和volatile前后的两个“__”字符,对C语言的一种扩充,后面我们还要讲到。先来看括号里面加上了引号的汇编指令。这是一条8位输出指令,如前所述在操作符上加了后缀“b”以表示这是8位的,而0x80因为是常数,即所谓“直接操作数”,所以要加上前缀“$”,而寄存器名al也加了前缀“%”。知道了前面所讲AT&T格式与Intel格式的不同,这就是一条很普通的汇编指令,很容易理解。
在同一个asm语句中也可以插入多行汇编程序。就在同一个文件中,在不同的条件下,__SLOW_DOWN_IO又有不同的定义:
#define __SLOW_DOWN_IO __asm__ __volatile__(“jmp 1f \nl:\tjmp 1f \n1:”)
这就不怎么直观了。这里,一共插入了三行汇编语句,“\n”就是换行符,而“\t”则表示TAB符。将之翻译成下面的格式而交给gas去汇编:
jmp 1f
1: jmp 1f
1:
这里转移指令的目标1f表示往前(f表示forward)找到第一个标号为1的那一行。相应地,如果是1b就表示往后找。这也是从早期Unix汇编代码中继承下来的,读过Unix第6版的读者大概都还能记得。所以,这一小段汇编代码的用意就在于使CPU空做两条跳转指令和消耗掉一些时间。既然是要消耗掉一些时间,而不是要节省一些时间,那么为什么要用汇编语句来实现,而不是在C里面来实现呢?原因在于想要对此有比较确切的控制。如果用C语言来消耗一些时间的话,你常常不能确切地知道经过编译以后,特别是经过优化的话,最后产生的汇编代码究竟怎样。
如果读者觉得这毕竟还是容易理解的话,那么下面这一段(取自include/asm/)就困难多了:
static __inline__ void atomic_add(int i, atomic_t *v)
{
__asm__ __volatile__(
LOCK "addl %1,%0"
:"=m" (v->counter)
:"ir" (i), "m" (v->counter));
}
一般而言,往C代码中插入汇编语言的代码片段要比“纯粹”的汇编语言代码复杂得多,因为这里有个怎样分配使用寄存器,怎样与C语言代码中的变量结合的问题。为了这个目的,必须对所用的汇编语言作更多的扩充,增加对汇编工具的指导作用。其结果是其语法实际上变成了既不同于汇编语言,也不同于C语言的某种中间语言。
下面,先介绍一下插入C代码中的汇编成分的一般格式,并加以解释。以后,在我们走过各种情景时碰到具体的代码时还会加以提示。
插入C代码中的一个汇编语言代码片段可以分成四部分,以“:”号加以分隔,其一般形式为:
指令部: 输出部: 输入部: 损坏部
注意不要把这些“:”号跟程序标号中所用的(如前面的1:)混淆。
第一部分就是汇编语句本身,其格式与在汇编语言程序中使用的基本相同,但也有区别,不同之处下面会讲到。这一部分可以称