呼和浩特市网站公司电话,帝国cms手机网站教程,洛阳市建设监理协会网站,深圳优化怎么做搜索基本内联汇编是最简单的内联形式#xff0c;其格式为#xff1a;
asm [volatile] (“assembly code”)
各关键字之间可以用空格或制表符分隔也可以紧凑挨在一起不分隔#xff0c;各部分意义如下#xff1a;
关键字asm用于声明内联汇编表达式#xff0c;这是内联汇编固定…基本内联汇编是最简单的内联形式其格式为
asm [volatile] (“assembly code”)
各关键字之间可以用空格或制表符分隔也可以紧凑挨在一起不分隔各部分意义如下
关键字asm用于声明内联汇编表达式这是内联汇编固定的部分不可少。
asm和__asm__是一样的是由gcc定义的宏#define __asm__ asm。
因为gcc有个优化选项-O可以指定优化级别。当用-O来编译时gcc按照自己的意图优化代码说不定就会把自己所写的代码修改了。关键字volatile是可选项它告诉gcc“不要修改我写的汇编代码请原样保留”。volatile和__volatile__是一样的是由gcc定义的宏#define __volatile__ volatile。
“assembly code”是咱们所写的汇编代码它必须位于圆括号中而且必须用双引号引起来。这是格式要求只要满足了这个格式asm [volatile] (“”)assembly code甚至可以为空。
下面说下assembly code的规则
1.指令必须用双引号引起来无论双引号中是一条指令或多条指令。2.一对双引号不能跨行如果跨行需要在结尾用反斜杠’\’转义。3.指令之间用分号’;’或换行符’\n’或换行符加制表符’\n’’\t’分隔。
提醒一下即使是指令分布在多个双引号中gcc最终也要把它们合并到一起来处理合并之后指令间必须要有分隔符。所以当指令在多个双引号中时除最后一个双引号外其余双引号中的代码最后一定要有分隔符这和其它编程语言中表示代码结束的分隔符是一样的如
asm(“movl $9,%eax;””pushl %eax”)正确
asm(“movl $9,%eax””pushl %eax”)错误
大家注意在内联汇编中咱们要注意操作数的顺序啦现在是和intel反着的。
给大家举个例子见文件inlineASM.c 1 char* strhello,world\n;2 int count 0;3 void main(){4 asm(pusha; \5 movl $4,%eax; \6 movl $1,%ebx; \7 movl str,%ecx; \8 movl $12,%edx; \9 int $0x80; \
10 mov %eax,count; \
11 popa \
12 );
13 }代码inlineASM.c是演示用汇编代码直接调用“系统调用”write来打印字符患该系统调用执行后会返回打印的字符数。
第1~2行定义了两个全局变量待打印的字符串是strcount是用来存储返回值
第4~12行是内联汇编这是咱们之前说过的c语言中跨过运行库直接调用系统调用的实例。这完全是ATT风格的汇编语句寄存器前面加前缀%立即数前面加前缀$操作数由左到右的顺序。似乎看上去很简单。
第4行将8个通用寄存器压栈ATT中的汇编指令是pushaintel中的是pushad。
第5行是传入第4号系统调用这就是write的调用号。
第6~8行是为write系统调用传入参数前面说系统调用的时候有讲过参数传递所用到的寄存器不再赘述。
第9行用int 0x80执行系统调用在ATT中立即数的地位比较低要加$前缀才表示数字为立即数常数。
第10行是获取write的返回值返回值都是存储在eax寄存器中所以将其复制到变量count中。
好啦编译运行看结果如图 大家注意到没有inlineASM.c中的变量count和str是定义为全局变量。对的在基本内联汇编中若要引用c变量只能将它定义为全局变量。如果定义为局部变量链接时会找不到这两个符号这就是基本内联汇编的局限性简单的东西往往功能不够强大所以咱们还得学下扩展内联汇编形式下一节走起。