在线汇编编写代码

本文详细介绍了如何在C语言程序中嵌入汇编语言,以提高程序效率和实现特定功能。文章讨论了两种汇编与C结合的方法:独立汇编程序和在线汇编。重点讲述了GCC的在线汇编指令格式,包括汇编指令模板、操作数、约束符等关键要素,并给出了多个实例,展示了如何通过GCC的嵌入式汇编实现对端口寄存器的读写操作。
摘要由CSDN通过智能技术生成

为了使C语言程序具有更高的效率和更多的功能,需在C语言程序里嵌入用汇编语言编写的子程序。一方面是为提高子程序的执行速度和效率;另一方面,可解决某些用C语言程序无法实现的机器语言操作。而C语言代码与汇编语言代码的接口是任何C编译器毋庸置疑要解决的问题。

    通常,有两种方法可将汇编语言代码与C语言代码联合在一起。一种是把独立的汇编语言程序用C函数连接起来,通过API (Application Program Interface) 的方式调用;另一种就是我们下面要讲的在线汇编方法,即将直接插入式汇编指令嵌入到C函数中。

 C语言的嵌入式汇编

    为了使C语言程序具有更高的效率和更多的功能,需在C语言程序里嵌入用汇编语言编写的子程序。一方面是为提高子程序的执行速度和效率;另一方面,可解决某些用C语言程序无法实现的机器语言操作。而C语言代码与汇编语言代码的接口是任何C编译器毋庸置疑要解决的问题。

    通常,有两种方法可将汇编语言代码与C语言代码联合在一起。一种是把独立的汇编语言程序用C函数连接起来,通过API (Application Program Interface) 的方式调用;另一种就是我们下面要讲的在线汇编方法,即将直接插入式汇编指令嵌入到C函数中。

     采用GCC规定的在线汇编指令格式进行指令的输入,是GCC实现将?nSP?汇编指令嵌入C函数中的方法。GCC在线汇编指令格式规定如下:

asm (“汇编指令模板”:输出参数:输入参数:clobbers参数)

若无clobber参数,则在线汇编指令格式可简化为:

asm (“汇编指令模板”:输出参数:输入参数)

下面,将对在线汇编指令格式中的各种成分之内容进行介绍。

1) 汇编指令模板

    模板是在线汇编指令中的主要成分,GCC据此可在当前位置产生汇编指令输出。例如,下面一条在线汇编指令:

    asm ("%0 += %1" : "+r" (foo) : "r" (bar))

    此处,"%0 += %1"就是模板。其中,操作数"%0""%1"作为一种形式参数,分别会由第一个冒号后面实际的输出、输入参数取代。带百分号的数字表示的是第一个冒号后参数的序号。

    如下例:

    asm ("%0 = %1 + %2" : "=r" (foo) : "r" (bar), "i" (10))

    "%0"会由参数foo取代,"%1"会由参数bar取代,而"%2"则会由数值10取代。

    在汇编输出中,一个汇编指令模板里可以挂接多条汇编指令。其方法是用换行符'\n'来结束每一条指令,并用Tab键符'\t'将同一模板产生在汇编输出中的各条指令在换行显示时缩进到同一列,以使汇编指令显示清晰。如下例:

asm ("%0 += %1\n\t%0 += %1" : "+r" (foo) : "r" (bar))

2) 操作数

    在线汇编指令格式中,第一冒号后的参数为输出操作数,第二冒号后的参数为输入操作数,第三冒号后跟着的则是clobber操作数。在各类操作数中,引号里的字符代表的是其存储类型约束符;括弧里面的字符串表示的是实际操作数。

    如果输出参数有若干个,可用逗号“,”将每个参数隔开。同样,该法则适用于输入参数或clobber参数。

3) 操作数约束符

    约束符的作用在于指示GCC,使用在汇编指令模板中的操作数的存储类型。表4.9列出了一些约束符和它们分别代表的操作数不同的存储类型,也列出了用在操作数约束符之前的两个约束符前缀。

4) GCC在线汇编指令举例

1asm ("%0 = %1 + %2" : "=m" (foo) : "r" (bar), "i" (10))

   操作数foobar都是局部变量。bar的值会分配给寄存器(此例中寄存器为R1),而foo的值会置入存储器中,其地址在此由BP寄存器指出。GCC对此会产生如下代码:

// GCC在线汇编起始

[BP] = R1 + 10

// GCC在线汇编结束

注意,本在线汇编指令产生的汇编代码不能被正确汇编。正确的在线汇编指令应当是:

asm ("%0 = %1 + %2" : "=r" (foo) : "r" (bar), "i" (10))

它产生如下的汇编代码:

// GCC在线汇编起始

R1 = R4 + 10

// GCC在线汇编结束

2

int a;

int b;

#define SEG(A,B) asm("%0 = seg %1" : "=r" (A) : "p" (&B));

int main(void)

{

  int foo;

  int bar;

  SEG(foo, a);

  SEG(bar, b);

  return foo;

}

3asm ("%0 += %1" : "+r" (foo) : "r" (bar))

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值