本质:
为了在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:输出寄存器中大小为四字节的部分