内嵌汇编的语法

来源:互联网 发布:网络攻击与防范 ppt 编辑:程序博客网 时间:2024/05/17 07:39

在gcc中,可以使用__asm__表示后面的代码为内嵌汇编代码,__volatile__表示编译器不要优化代码,后面的指令保留原样,内嵌汇编语法如下:

 

1.汇编语言模板

语句之间使用";"、"/n"或"/n/t"分开。指令中的操作数可以使用占位符引用C语言变量,操作数占位符最多为10个,名称如下:

 

指令中使用占位符表示的操作数,总被视为long型(4字节),但对其施加的操作根据指令可以是字或字节,当把操作数当作字或者字节使用时,默认为低字或者低字节。对字节操作可以显式地指明是低字节还是次字节,方法是在%和序号之间插入一个字母,"b"代表低字节,"h"代表高字节。

 

2.输出部分

输出部分描述输出操作数,不同的操作数描述符之间用逗号格开,每个操作数描述符由限定字符串和C语言变量组成。

 

3.输入部分

 

4.限定字符

 

5.破坏描述符部分

破坏描述符用于通知编译器我们使用了哪些寄存器或内存。

 

编译器优化

由编译器优化或者硬件重新排序引起的问题的解决办法是以特定顺序执行的操作之间设置内存屏障(memory barrier),Linux提供了一个宏用于解决编译器的执行顺序问题。

 

这个函数通知编译器插入一个内存屏障,但对硬件无效,编译后的代码会把当前CPU寄存器中的所有改过的数值存入内存,需要这些数据的时候再重新从内存中读出。

 

 

C语言关键字volatile表明某个变量的值可能在外部被改变,因此对这些变量的存取不能缓存到寄存器,每次使用时需要重新存取。

 

memory描述符告诉gcc以下内容。

不要将该段内嵌汇编指令与前面的指令重新排序,也就是说在执行内嵌汇编代码之前,它前面的指令都执行完毕。

不要将变量缓存到寄存器,因为这段代码可能会用到内存变量,而这些内存变量会以不可预知的方式发生改变,因此gcc插入必要的代码先将缓存到寄存器的变量值写回内存,如果后面又访问这些变量,需要重新访问内存。

 

如果汇编指令修改了内存,但是gcc本身却察觉不到,因为在输出部分没有描述,此时就需要在修改描述部分增加memory,告诉gcc内存已经被修改,gcc得知这个消息后,就会在这段指令之前,插入必要的指令将前面因为优化Cache而到寄存器中的变量值先写回内存,如果以后又要使用这些变量,则再重新读取。

 

 

原创粉丝点击