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

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

当需要在C语言的程序中嵌入一段汇编语言程序段时,可以使用gcc提供的“ asm”语

句功能。例如,下面这么一行代码:

#define __SLOW_DOWN_IO __asm__ __volatile__(“outb %al, $0x80 ”)

这里,暂时忽略在asm和volatile前后的两个“ __”字符,这也是gcc对C语言的一种 扩充,后面我们还要讲到。先来看括号里面加上了引号的汇编指令。这是一条8 位输出指

令,如前所述在操作符上加了后缀“ b”以表示这是8位的,而0x80因为是常数,即所谓 “直接操作数”,所以要加上前缀“ $”,而寄存器名 al 也加了前缀“ %”。知道了前面所讲 AT&T格式与In tel格式的不同,这就是一条很普通的汇编指令,很容易理解。

在同一个asm语句中也可以插入多行汇编程序。就在同一个文件中,在不同的条件下, _SLOW_DOWN _1(又有不同的定义:

jmp 1f n1: ”)“ \n ”就是换行符,而“ \t ”则 gcc将之翻译成下面的格式而交给

jmp 1f n1: ”)

“ \n ”就是换行符,而“ \t ”则 gcc将之翻译成下面的格式而交给 gas去汇编:

jmp 1f

jmp 1f

这就不怎么直观了。这里,一共插入了三行汇编语句, 表示TAB符。所以

1:

1:

这里转移指令的目标 1f 表示往前( f 表示 forward )找到第一个标号为 1 的那一行。相 应地,如果是 1b 就表示往后找。这也是从早期 Unix 汇编代码中继承下来的,读过 Unix 第 6 版的读者大概都还能记得。所以,这一小段汇编代码的用意就在于使CPU 空做两条跳转

指令和消耗掉一些时间。既然是要消耗掉一些时间,而不是要节省一些时间,那么为什么 要用汇编语句来实现,而不是在 C 里面来实现呢?原因在于想要对此有比较确切的控制。 如果用 C 语言来消耗一些时间的话,你常常不能确切地知道经过编译以后,特别是经过优 化的话,最后产生的汇编代码究竟怎样。

如果读者觉得这毕竟还是容易理解的话, 那么下面这一段(取自 include/asm/atomic.h ) 就困难多了: 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:)混淆。

第一部分就是汇编语句本身,其格式与在汇编语言程序中使用的基本相同,但也有区 别,不同之处下面会讲到。这一部分可以称为“指令部” ,是必须有的,而其他各部分则可 视具体情况而省略,所以在最简单的情况下就与常规的汇编语句基本相同,如前面的两个 例子那样。

当将汇编语言的代码片段嵌入到 C代码中时,操作数与C代码中的变量如何结合显然 是个问题。在本节开头的两个例子中,汇编指令都没有产生与C程序中的变量结合的问题, 所以比较简单。当汇编指令中的操作数需要与 C 程序中的某些变量结合时,情况就复杂多 了。这是因为:程序员在编写嵌入的汇编代码时,按照程序逻辑的要求很清楚应该选用什 么指令, 但是却无法确切地知道 gcc 在嵌入点的前后会把哪一个寄存器分配用于哪一个变 量,以及哪一个或哪几个寄存器是空闲着的 。而且,光是被动地知道 gcc 对寄存器的分配 情况也还是不够,还得有个手段把使用寄存器的要求告知 gcc,反过来影响它对寄存器的分 配。当然,如果 gcc 的功能非常强,那么通过分析嵌入的汇编代码也应该能够归纳出这些 要求,再通过优化,最后也能达到目的。但是,即使那样,所引入的不确定性也还是个问 题,更何况要做到这样还不容易。针对这个问题,gcc采取了一种折中的办法:程序员只提 供具体的指令而对寄存器的使用则一般只提供一个“样板”和一些约束条件,而把到底如 何与变量结合的问题留给gcc

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值