第51部分- Linux x86 64位汇编内嵌汇编
用汇编编写的程序运行速度快,但开发效率很低。如果只是想对关键代码段进行优化,更好的办法是将汇编指令嵌入到 C 语言程序中。但在 C 代码中嵌入汇编语句要比"纯粹"的汇编语言代码复杂,因为需要解决如何分配寄存器,以及如何与C代码中的变量相结合等问题。
GCC 提供了很好的内联汇编支持,最基本的格式是:
__asm__("asm statements");
Instruction List是汇编指令序列,可以是空的,比如: __asm__ ("");只不过这条语句没有什么意义。
__volatile__是GCC关键字volatile的宏定义,如果用了它,则是向GCC声明“不要动我所写的Instruction List,需要原封不动的保留每一条指令”,否则当使用了优化选项(-O)进行编译时,GCC将会根据自己的判断决定是否将这个内联汇编表达式中的指令优化掉。
示例
#include "stdio.h"
int main()
{
int a = 10, b = 0;
__asm__ __volatile__("movl %1,%%eax \n\t"
"movl %%eax,%0 \n\t"
:"=g"(b) /* 输出 */
:"g"(a) /* 输入 */
); /* 不受影响的寄存器 */
printf("Result: %d, %d \n", a, b);
return 0;
}
程序完成将变量a的值赋予变量b。
%%是寄存器前缀符号。
实例二
#include <string.h>
int main() {
char* str = "Hello World\n";
long len = strlen(str);
int ret = 0;
__asm__("movq $1, %%rax \n\t"
"movq $1, %%rdi \n\t"
"movq %1, %%rsi \n\t"
"movl %2, %%edx \n\t"
"syscall"
: "=g"(ret)
: "g"(str), "g" (len));
return 0;
}
gcc inlineasm.c -o inlineasm
这里涉及到输出修饰符。