|

楼主 |
发表于 2006-11-10 22:38:22
|
显示全部楼层
三、Linux下的汇编工具:
Linux下的汇编工具可谓百家争鸣,不像DOS下都要给MASM和TASM给控制了。但是Linux下每一种汇编工具都
有很大的区别,要想全部掌握几乎是不可能的,下面我介绍几种常用的汇编工具,重点介绍NASM及其使用
和语法。
1、GCC
GCC其实是GNU的C语言产品,但它支持Inline Assemble,在GCC中inline assemble使用就像宏一样,但它
比宏能更清楚更准确的表达机器的工作状态。
C是汇编编程的一个高度概括,它可以减少许多汇编中的麻烦,特别是在GCC这个C编译器中,assemble似乎
起不了多大的作用。
2、GAS
GAS是Linux各版本中基本的汇编工具,但它采用的是AT&T的语法标准与Intel的语法标准有很大的不同,对
于DOS编程的我们来说,学习起来是非常困难的。当然如果要精通Linux下的汇编编程,学习GAS也是非常必
要的,具体的语法标准可以参看Using GNU Assembler。
3、GASP
GASP是GAS的扩展,它增强了GAS对宏的支持。
4、NASM
NASM是linux中语法与DOS最为相像的一种汇编工具。虽说如此,它与MASM也是有着很大区别的。
l NASM的使用格式如下:
Nasm –f -o
例如:
Nasm -f elf hello.asm
将把hello.asm汇编成ELF object文件,而
Nasm -f bin hello.asm -o hello.com
会把hello.asm汇编成二进制可执行文件hello.com
Nasm –h
将会列出NASM命令行的完整说明。
NASM不会有任何输出,除非有错误发生。
-f 在Linux下主要有aout和ELF两种,如果你不确定你的Linux系统应该用AOUT还是ELF,可以在NASM目录中
输入 File nasm ,如果输出nasm: ELF 32-bit LSB executable i386 (386 and up) Version 1表示是ELF
,如果输出nasm: Linux/i386 demand-paged executable (QMAGIC)表示是aout。
l NASM与MASM的主要不同:
首先与linux系统一样,nasm是区分大小写的,Hello与hello将是不同的标识符,如果要汇编到DOS或OS/2
,需要加入UPPERCASE参数。
其次,nasm中内存操作数都是以[ ]表示。
在MASM中
foo equ 1
bar dw 2
mov ax,foo
mov ax,bar
将被汇编成完全不同的指令,虽然它们在MASM中的表达方式完全一样。而NASM完全避免了这种混乱,它使
用的是这样的规则:所有对内存的操作都必须通过[ ]来实现。例如上例中对bar的操作就要写成如下形式
mov ax,[bar]。由此可见,nasm中对offset的使用也是没有必要的(nasm中无offset)。Nasm对[ ]的使用
与masm也有所不同,所有的表达式都必须写在[ ]中,下面举两个例子来说明:
Masm Nasm
Mov ax,table[di]
Mov ax,[table+di]
Mov ax,es:[di]
Mov ax,[es:di]
Mov ax,[di]+1
Mov ax,[di+1]
Nasm 中不存储变量类型,原因很简单masm中通过[ ]寻址方式的变量也必须要指定类型。Nasm中不支持
LODS, MOVS, STOS, SCAS, CMPS, INS, OUTS,只支持lodsb、lodsw等已经指定类型的操作。Nasm中不再有
assume操作,段地址完全取决于存入段寄存器的值。
关于NASM的使用方法及语法还可以参阅NASM使用手册。
结论:
我认为不论是在Windows/DOS下还是在Linux下完完全全用汇编编一个大型程序已经是不可能了,也不会有
人愿意去这样做。在windows下我们可以用VC,在Linux/Xwindows下我们可以用C甚至C++ Builder,但是像
VC、C++ Builder之类的工具尽量隐藏了底层的调用,同时也阻隔了成为高手的机会,因为编出来的程序无
法了解它的执行过程也就使编程中最重要的“可预测”性变得很低。正因为如此汇编才有它存在的必要性
,同时还有一个更重要的原因,正如《超级解霸》的作者梁肇新所说:“编程序的重点不是“编”,而是
调试程序,理论上的完美在实现的时候会遇到很多细节问题,这些问题必须调试才能解决。我的编程习惯
是一天写五天调试,《超级解霸》是调试出来的,而不是写出来的。调试就涉及到汇编的问题,不进行汇
编级的调试是不彻底的,也不能让人放心。
呵呵,搞定了 |
|