扩展内联汇编基础

Posted 重言

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了扩展内联汇编基础相关的知识,希望对你有一定的参考价值。

本质: 

  为了在C语言中利用汇编语言,需要一种格式,将C语言的变量准确地输入和输出到汇编语言中当作操作数,同时还不能和其他代码编译的汇编语言冲突。

格式:

  asm [volatile] ("assembly code" : output : input : clobber/modify)

  assembly code

  和基本内联汇编差不多,但是里面的寄存器使用%%作前缀

  output:

  "操作数修饰符 约束名“ (C变量名)

    操作数修饰符: 

    =:表示只写,即对应操作数只能用来写

    +:表示可读可写,即操作数先需要读入,然后再写

    &:表示这个操作数要独占所约束的寄存器,只供output使用;有多个修饰符时,它要挨着约束名

  input:

  ”【操作数修饰符】约束名“(C变量名)

    操作数修饰符:

    %:该操作数可以和下一个操作数互换

  约束名:

  寄存器约束:要求GCC使用哪个寄存器,将input或output中变量约束在某个寄存器中

  内存约束:将input和output中的变量的地址当作操作数,也就是直接对指针进行操作

  立即数约束:要求GCC在传值的时候不同过内存或者寄存器,而是作为立即数传递

  通用约束:只在input中,表示和某个操作数使用一样的约束

  占位符:      

    序号占位符:

    使用0~9,在assembly code中使用%0-9表示引用,所以%%修饰寄存器

    名称占位符:

    【名称】input\\output,在code中直接用%[名称]便可引用

  clobber/modify:

  目的: 

  通知GCC修改了哪些寄存器或者内存

  寄存器修改直接用” reg" 便可,用逗号分割

  内存修改用"memory":①使用ESI和EDI复制数据的时候会修改②当清除寄存器缓存的时候会修改,如果变量不变,那么直接从寄存器中读值会快很多。但是如果变量变了,即内存在变,那么需要经常读内存,所以就用"memory"(也可以用volatile声明变量表示变量不稳定)

  其他:

  机器模式:”a"表示送入al\\ax\\eax,那么到底是哪个呢?这时候需要用机器模式,让他在更细的粒度上描述操作数,而机器模式由操作码决定,如下:

  h:输出寄存器高位部分的一字节

  b:输出寄存器低位部分的一字节

  w:输出寄存器中大小为二字节的部分

  k:输出寄存器中大小为四字节的部分

以上是关于扩展内联汇编基础的主要内容,如果未能解决你的问题,请参考以下文章

GCC 扩展内联汇编简介

扩展内联汇编:输入和输出的相同变量

扩展内联汇编 gcc - 计算二次公式根

如何在没有扩展内联 asm 的情况下在 gcc 内联汇编中声明和初始化局部变量?

内联汇编的使用

优化系列汇编优化技术:x86架构内联汇编及demo