内联汇编:在C/C++代码中嵌入汇编代码。
汇编的用武之地:
在GNU下,在高级语言中嵌汇编语言用关键字asm来实现,简单的格式如下:
asm( “assembly code” );
C中嵌汇编的例子,记录C中嵌汇编的格式:
1 #include <stdio.h> 2 3 int main(void) 4 { 5 //AT&T asm systemcall: exit 6 asm( "movl $1, %eax\n\t" 7 "movl $0,%ebx\n\t" 8 "int $0x80"); 9 10 //Print string on screen 11 printf("Hello ""world"" C\n"); 12 13 return 0; 14 } |
在C中内嵌的汇编代码能够处理在C中的变量,可惜只能处理全局变量(已验证)。以下笔记示例:
1 #include <stdio.h> 2 3 int a; 4 int b; 5 int c; 6 7 int main(void) 8 { 9 a = b = 1; 10 c =0; 11 //AT&T asm system call: exit 12 asm( "movl a,%eax\n\t" 13 "movl b, %ebx\n\t" 14 "addl %eax,%ebx\n\t" 15 "movl %ebx, c"); 16 17 //Print string on screen 18 printf("Result is %d\n", c); 19 20 return 0; 21 } |
使用以上的内敛汇编代码有一定的局限性,比如在内敛汇编代码中只能访问C的全局变量。而在扩展内敛汇编代码内就能够让内敛汇编代码访问C的任何变量。GNU的扩展内敛汇编笔记如下。
asm (“assembly code”
:output locations
:input operands
:change dregisters);
对于后三块,没有的模块可以直接省略。非最后一部分省略时冒号不可被省略。
output locations,input operands具有的格式:
“constraint1”(variable1),“constraint2”(variable2)…
还是针对于以上的内敛汇编代码,将全局变量改为局部变量,用扩展内敛汇编去访问C中的变量。
1 #include <stdio.h> 2 3 4 int main(void) 5 { 6 int a, b, c; 7 8 a = b = 1; 9 c =0; 10 //AT&T asm system call: exit 11 asm( "movl $0,%%eax\n\t" 12 "addl %%ebx,%%ecx\n\t" 13 "addl %%ecx,%%eax\n\t" 14 : "=a"(c) 15 : "b"(a),"c"(b) 16 ); 17 18 //Print string on screen 19 printf("Result is %d\n", c); 20 21 return 0; 22 } |
用寄存器来作为C变量的存储地,再经汇编代码处理。这个过程其实就是将变量的值拷贝到各寄存器中,然后操作各寄存器,再将作为输出的变量重新赋值。不过为什么在这种情况下要在寄存器前面加两个%应该与%本身功能相关,点到为止,遇到再议。
当需要内敛汇编代码处理的代码数量较多时,可能会有不知道用哪个寄存器来保存输入变量才比较,恐怕有心有余而力不足的赶脚。使用占位符可解决此烦恼。
占位符用除寄存器外的其它constraint[可查看《Professional Assembly language》page402]来表示。如:
asm( "addl %1, %2\n\t" "addl %2, %0\n\t" : "=r"(c) : "r"(a), "r"(b) ); |
使用占位符的情况还可以如此:
asm ( “addl %[value1], %[value2]” : [value2] “=r” (data2) :[value1] “r”(data1)); |
内存空间的限制符为m。在使用内存空间时,需要用一个寄存器来作为中间存储。
还有其它形式的扩展内敛汇编,形体都差不多。在实际编程中可根据需求和爱好进行选择。
在asm之后加了volatile之后,表明括号内的汇编代码不被优化。这些是volatile关键字的作用,道理深着。
在GNU下可使用asm来表示内敛的汇编代码。如果是在ANSC C中编写内敛汇编代码,需要用__asm_来替换asm。同时volatile也需要换成__volatile_。
在C/C++中使用内敛汇编的很多形式为宏。即将内敛汇编定义成宏供C/C++代码调用。将内敛汇编定义成宏的形式更加方便。定义宏的方式跟在C中定义C宏的方法一致,只是宏的形式跟以上笔记的内敛汇编的形式一致。
CNote Over。
本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。