其他分享
首页 > 其他分享> > rdi

rdi

作者:互联网

https://blog.csdn.net/ganggexiongqi/article/details/24435839  

  对一个应用程序员来讲,了解汇编不是必需的,更少有手写纯汇编的需求。但是如果能了解些基本的汇编知识,对程序调试和一些语言特性的理解是大有裨益的。本文介绍 AT&T 语法的汇编的要点以及 GCC 使用的内联汇编(inline assembly)的使用。

AT&T 汇编

  AT&T 汇编是 GCC 所采用的语法,要点:

  通用寄存器(x86_64):

  X86_64 下 ABI 调用约定:

GCC 内联汇编

  内联汇编允许在 C/C++ 代码中嵌入汇编代码,以优化关键代码或者使用架构特有的指令。内联汇编的基本格式如下:

 

 

  1.   asm [volatile] ( <assembler template>
  2.   : ["constraints"(var)] [,"constraints"(var)] /* output operands */
  3.   : ["constraints"(var)] [,"constraints"(var)] /* input operands */
  4.   : ["register"] [,"register"] [,"memory"] /* clobbered registers */
  5.   );

 

    中括号中为可选部分,尖括号为必选部分。圆括号内由 ‘:’ 分割为四个部分:

  常用的 constraints 为:

  输出 constraints 中需要下面至少一个『修饰符』(constraints modifier)作为前缀:

  下面看几个示例:

 

 

  1.   asm ("":::); //~ nothing
  2.   asm ("incl %%eax\n\t":::"eax"); //~ access register directly
  3.   asm ("movq $1, %0\n\t" : "=m"(var)); //~ write 1 to var
  4.   asm ("mov %0, %%eax\n\t" : : "m"(var)); //~ read from var to eax
  5.   //~ read a to eax, read b to either ebx|ecx|edx|edi|esi, add it to eax, write back eax to a
  6.   asm ("addl %1, %0\n\t" : "+a"(a) : "r"(b));
  7.   asm ("incq global_var\n\t" :::"memory"); //~ access global_var directly
  8.   asm ("incl %0\n\t" : "+q"(var)); //~ read var to either eax|ebx|ecx|edx, increase it, write it back to var
  9.   asm ("incl %0\n\t" : "=q"(var) : "0"(var)) //~ the same as above, constraint 0 means using the same register
  10.   asm ("incl %[__var__]\n\t" : [__var__]"+q"(var)); //~ use user-defined placeholder


 

最后一个示例使用了用户自定义的占位符,通常在输入输入变量较多的情况下使用,省得逐个地对应。
  在汇编中调用 printf:

  1.   #include <stdio.h>
  2.   int
  3.   main()
  4.   {
  5.   char *fmt = "Hello, %s\n";
  6.   char *s = "World";
  7.   int ret = 0;
  8.   asm (" callq printf\n\t"
  9.   : "=a"(ret)
  10.   : "D"(fmt), "S"(s));
  11.   printf("ret: %d\n", ret);
  12.   return 0;
  13.   }


  在汇编中进行系统调用:

  1.   int
  2.   sys_write(int fd, const char *buf, size_t n)
  3.   {
  4.   int ret;
  5.   asm (
  6.   "syscall\n\t"
  7.   : "=a"(ret)
  8.   : "0"(1), "D"(fd), "S"(buf), "d"(n)
  9.   );
  10.   return ret;
  11.   }
  12.    
  13.   int
  14.   main()
  15.   {
  16.   char *s = "Hello, World\n";
  17.   printf("%d\n", sys_write(fileno(stdout), s, strlen(s)));
  18.   return 0;
  19.   }


参考资料

标签:汇编,操作数,eax,寄存器,var,rdi,asm
来源: https://www.cnblogs.com/Janly/p/14615861.html