NASM可真是个好东西。
俺以前特别菜的时候用过masm,主要是研究C语言参数调用协议的(ASM和C混合编程相关),什么高级用法都不会。不过masm的语法也够繁琐,不合胃口。
传说中的gas我真的没用过 ,看了赵博的书上成篇的gas代码我就头痛,AT&T的汇编格式真的很别扭。
首先源操作数和目的操作数和Intel汇编相反,这和我们通常的编程习惯相反。我举个例子,strcpy()函数,该函数第一个参数是目的字符串,第二个参数是源字符串。同样的还有诸如memcpy()等等。我们已经太习惯这种目的在前,源在后的形式了,所以AT&T汇编肯定别扭= =。另外就是寄存器前加%号啊等等很麻烦的设定。
不过话说回来gcc内嵌的汇编都是AT&T的格式(gcc使用gas作为其代码的最终生成工具,即.c/.cpp->.S->.o),所以这个想躲也躲不掉= =,总之我目前是打算尽量用nasm书写汇编,逼不得以再说gcc内嵌,单纯的.S打死也不写!!!
nasm写纯二进制码很easy,稍微不爽的就是它的ORG只能用一次,表示整个汇编文件的起始地址,于是乎就要使用大量的times n - ($- $$) db 0来跳过一定数目的字节,确实麻烦,且容易出错,呵呵。
不过瑕不掩瑜,nasm还是有许多过人之处的。它的地址和标识符的概念很符合我的个人观念,即所有标识符都是地址,要获得值就要加[ ]。想想masm中丑陋的OFFSET关键字,以及各种别扭的语义,这样真是方便多了。
nasm支持至少三种16进制的书写格式:C/as86风格(0x##),MASM/TASM风格(##h),Pascal风格($##)。还有一点至关重要,nasm跨平台,而且free!
nasm还可以incbin,就是包含二进制文件,这样很容易用nasm直接制作磁盘镜像,而不需要自己动手写程序或者使用别的工具。举个例子吧:
makeboot.asm:
incbin "setup.bin"
times 512 * 3 - ($ - $$) db 0
incbin "head.bin"
times 1474560 - ($ - $$) db 0
汇编命令: nasm -f bin -o boot.img makeboot.asm
假设我写了一个bootsect.asm,编出来的bin大小512字节(引导扇区),还有一个setup.asm,编出来setup.bin大小在1024字节以内,上面的代码就可以把bootsect.bin放入第一个扇区,setup.bin放入2、3扇区,其余扇区全部填0,总大小1.44MB。
这个镜像在boch上面跑没任何问题。不过我使用的VM,就不要那么麻烦。什么VPC啊的,还非要检查镜像大小是否等于1.44或1.38。VM不管,不足一律填零。所以上述代码我是没怎么用到,给还在使用VPC的人去用吧。
废话就说这么多,nasm偶还是只用了一些基本功能,不过也好,写出的代码可读性强(限和我一样的初学者,呵呵)。
今天就到此为止吧。