qt内嵌汇编

来源:互联网 发布:安捷伦34401a 编程 编辑:程序博客网 时间:2024/06/13 03:47

我们先来看一个简单的内嵌汇编:

    int a = 6;    int b = 1;    asm volatile("movl %0,%1" : "=r" (a) : "r" (b));    printf ("a = %d\nb = %d\n", a, b);    system("pause");

先介绍一下这段代码的内容:

“__asm__”表示后面的代码为内嵌汇编,“asm”是“__asm__”的别名。 

“__volatile__”表示编译器不要优化代码,后面的指令保留原样, 
“volatile”是它的别名。括号里面是汇编指令。 

“movl %0,%1”是指令模板;“%0”和“%1”代表指令的操作数,称为占位符,最多十个。

注意对应关系:%0对应"=r" (a),%1对应"r" (b)。

“a”前面 的限制字符串是“=r”,其中“=”表示“a”是输出操作数,“r 
”表示需要将“a”与某个通用寄存器相关联,先将操作数的值读入寄存器,然后 
在指令中使用相应寄存器,而不是“a”本身,当然指令执行完后需要将寄存器中的值 
存入变量“a”,从表面上看好像是指令直接对“a”进行操作,实际上GCC 
做了隐式处理,这样我们可以少写一些指令。“b”前面的“r”表示该表达式需要先放入 
某个寄存器,然后在指令中使用该寄存器参加运算。 

所以:

    asm volatile("movl %0,%1" : "=r" (a) : "r" (b));
表示将b读入寄存器,并且输出给a所以现在a和b都等于1.

如果我们把代码改成:

asm volatile("movl %0,%1" : "=r" (b) : "m" (a));
表示将a的内存地址读入寄存器,所以ab都等于a的内存地址:

指令movl 
允许寄存器到寄存器,立即数到寄存器等,但是不允许内存到内存的操作,因此两个操作数 
不能同时使用“m”作为限定字符。 

内嵌汇编语法如下: 

__asm__( 
汇编语句模板: 
输出部分: 
输入部分: 
破坏描述部分) 

“=”表示他是一个输出操作数。 

“r”将输入变量放入通用寄存器,也就是eax ,ebx,ecx,edx,esi,edi中的一个 

“b”将输入变量放入ebx 
“c”将输入变量放入ecx 
“d”将输入变量放入edx 
“s”将输入变量放入esi 
“d”将输入变量放入edi 
“q”将输入变量放入eax,ebx ,ecx ,edx中的一个 

A”把eax和edx,合成一个64位的寄存器(uselong longs) 
“m”内存变量 
“o”操作数为内存变量,但是其寻址方式是偏移量类型,也即是基址寻址,或者是基址加变址寻址 
“V”操作数为内存变量,但寻址方式不是偏移量类型 
“,” 操作数为内存变量,但寻址方式为自动增量 
“p”操作数是一个合法的内存地址(指针) 
“g” 将输入变量放入eax,ebx,ecx ,edx中的一个或者作为内存变量 
“X”操作数可以是任何类型 

“I” 0-31 之间的立即数(用于32位移位指令) 
“J” 0-63 之间的立即数(用于64 位移位指令) 
“N” 0-255 ,之间的立即数(用于out 指令) 
“i” 立即数 
“n” 立即数,有些系统不支持除字以外的立即数,这些系统应该使用“n”而不是“i”

“=” 操作数在指令中是只写的(输出操作数) 
“+” 操作数在指令中是读写类型的(输入输出操作数) 

“t”第一个浮点寄存器 
“u”第二个浮点寄存器 
“G”标准的80387 

 asm volatile("addl %2,%0":"=r"(a): "r"(a),"r"(b));
//这段代码的意思是,将a读入寄存器,将b读入寄存器,相加,输出给a;




原创粉丝点击