gcc内联汇编示例

gcc内联汇编示例

通过中断获取鼠标信息并打印

首先作者是菜鸟,有不妥当的地方,可以讨论指教。

另外,x64的windows下,内联汇编受到很多限制,所以最后的实战在linux系统下完成。

前面的语法讲解,为了方便,也因为作者只会8086,所以用的8086语法。

计算机领域的技术日新月异,与时俱进太重要啦。进入正题吧。

在某些特殊情况下,通过内联汇编,可以提高程序效率,且更加灵活。下面以通过int 33h获取鼠标信息并打印为例。

一、基础语法

加上asm标识,后面直接括号内添加指令即可。其中可选[ volatile ],为不优化编译直接用这个指令

asm [ volatile ] ( AssemblerInstructions )
二、进阶语法

基础语法过于死板,当遇到输入输出时就无能为力,这个时候就可以用完整语法。

asm [volatile] ( AssemblerTemplate
                : OutputOperands
                : InputOperands
                : Clobbers)

进阶语法包括4个模块,每个模块用:隔开。其中,第一个模块AssemblerTemplate,是必须要有的,相当于汇编指令。后面三个可选,如果没有内容,也需要用:隔开。例子如下。调用33号中断使用03号功能。为了简便,在下面的例子中我使用8086汇编的语法也不考虑变量的长度!!!

asm ("mov ax,03h\n	"
     "int 33h		"
      : 
      : 
      : )

需要注意的是指令需要用双引号包围且换行需要转义。在实际编程中,通常使用’'\n" 后紧随一个制表符"(\t)“”,使得输出的汇编文件排版更加清晰。

小难点

第一个模块AssemblerTemplate中是没办法使用c语言的变量的,那么如何完成对C程序变量的访问

很明显,需要下面的输入输出模块去内联啦。

输出模块内联

我们要把ax的值给到一个c变量。会面临一个考验,那就是ax的位数是有限,比如32位,但我们long long int是64位,类似这些问题,肯定需要解决。但这个问题我们后面说,先把输出的格式搞定先。

语法很简单,把变量名用"()"扩起来就是。前面有一个可选项,如果你用默认的变量序号 “%n"来的话,不需要,当然绑定一个编号也是可以的。多个输出数用”,"号隔开即可。

 [asmSymbolicName]  constraint (cvariablename)

把cx和dx的值分别给到第0个和第1个输出参数。对了constraint是一个字符串,用来对后面的C变量进行限定,细节在后面会单独介绍。目前可以忽略。

int mouthX,mouthY;

asm ("mov ax,03h\n	"
     "int 33h\n		"
     "mov %0,cx\n	"
     "mov %1,dx\n	"
      : (mouthX), (mouthY)
      : 
      : )

与输出类似,那么就该输入了

输入模块

和输出模块差不多,比如我们要向什么地方输入直接写上即可,其中我们会看到 ”a“这是一个限定符,表示输入到哪里(用到了那个寄存器)。后面会讲到

int mouthX,mouthY;
int funNmb=3;

asm ("int 33h\n		"
     "mov %0,cx\n	"
     "mov %1,dx\n	"
      : (mouthX), (mouthY)
      :"a" (funNmb)
      : )

最后一个模块

破坏列表Clobbers

Clobbers部分的作用是让程序员告诉GCC汇编指令可能会修改哪些寄存器,这样GCC就会认为在asm语句执行完毕后,这些内容是无效的,进而在编译时会插入相应的保护现场和恢复现场的代码。所以把它称为”破坏列表“。

除了在”破坏列表“中指定被使用的寄存器外,其实还可以在输入输出时加上限定修饰符,这样被修饰的就不用再在”破坏列表“中出现。

限定修饰符constraint

asm汇编语句中操作数(输入输出)可使用的contraints(约束),约束告诉GCC操作数是否应该在寄存器中,以及在哪类寄存器中;是否在内存中,以及在哪类内存中;是否是常量,以及它可能的取值;此外约束还可以匹配输入操作和输出操作数

限定修饰符的使用比较麻烦,它包括限定符修饰符&约束修饰符。

最简单的限定符是由一组字母组成的字符串,其中每个字符描述了允许的一种类型操作数,常用的限定符如下:

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值