有时候,因为各种原因,我们需要用汇编代码实现一些程序功能。
有时候,是在C代码中嵌入一点汇编代码;有时候,则是创建纯汇编代码构成的.S文件。
用汇编代码写程序,主要会遇到两大麻烦:
1. 语法记不住,总是得翻阅资料。而且资料也经常不好查。
2. 不同平台环境,语法不统一。
不同处理器架构某些语法可能就不一样;甚至同一架构,同一种工具链,只是操作系统平台不同,也会导致语法不一样。例如,同样是x86平台,同样是gcc工具链。Linux平台的gcc与windows平台的mingw,就有语法上的不同。
因为上面两大麻烦,开发者可能经常会为此折腾很常时间。
笔者就经常为此备受煎熬。
不过,痛定思痛,也总结出些许经验技巧。
一. 嵌入式汇编技巧
函数内,尽量用C代码定义函数局部变量,实现各种运算。让C编译器尽可能为我们多做事。例如局部变量的空间分配啦,函数返回啦,等等。
只在最关键的地方,来一两行汇编代码。这一两行代码的目的,主要有两类,一是提示编译器为某个局部变量分配特定类型的存储器(例如寄存器),二是帮忙将某个特殊的寄存器的值取到我们所希望的局部变量中。一旦变量空间分配好了,或者要取的寄存器的值取好了,剩下的事全用C语言搞定。
这样使用嵌入式汇编最保险,因为编译器为我们搞定了各种事宜:)
二、编写.S文件的技巧
1. 变量定义
如果是一般的变量定义,我们肯定用C全局变量搞定啦。
既然用汇编,当然是因为有特殊性。但我们要定义的变量,除了特殊的地方,必然也有与普通全局变量相同的某些属性。
例如,他是不是已初始化数据,位于哪个section中,是只读的,还是可写的。
那好了,我们先写一个test.c文件,在里面定义一个全局变量a,让他尽可能与我们最终要定义的变量相同。然后,我们使用gcc -c -S test.c编译此文件,生成test.S文件。然后我们以test.S中变量a的定义为模板,稍做修改,就能定义出我们需要的最终变量了。
下面的贴子,windows平台mingw工具链的haha.S文件就是通过这种方法摸索出来的。
http://blog.csdn.net/crazycoder8848/article/details/19038885
2. 代码编写
还是老思路,尽量以已有代码为模板。
Linux内核源码就是我们的巨大宝库,里面的漂亮代码不要太多。
而且Linux内核代码还有一个好处,就是完整独立,从源码级就不依赖任何第三方代码,连C库都不依赖。
因此,我们可以多参考Linux内核源码,以之为模板来实现我们的代码。
以x86_64架构的内存拷贝为例,
arch\x86_64\lib\copy_page.S中就提供了相应的汇编代码的实现。
原文:http://blog.csdn.net/crazycoder8848/article/details/19048841