NASM汇编器和MASM汇编器一样,都可以生成适用于Win32平台的coff文件格式,这种文件格式可以被MS 的link.exe连接器连接成PE文件。通常,我们知道MASM可以通过includelib伪指令将导入库的名称传给连接器link.exe,告知它该从哪个库中导入所需外部符号,而NASM汇编器在这方面的能力却是有过之而无不及,它可以通过info段,将更多的连接参数传递给link.exe,下面的两段代码展示了两者之间的用法和差异:

NASM、MASM浅谈-编程知识网;filename: sayhellon.asm
NASM、MASM浅谈-编程知识网;
NASM、MASM浅谈-编程知识网;
cmd> nasm -fcoff -Xvc sayhellon.asm
NASM、MASM浅谈-编程知识网;
cmd> link sayhellon.obj
NASM、MASM浅谈-编程知识网

NASM、MASM浅谈-编程知识网extern _MessageBoxA@16    
;in user32.dll
NASM、MASM浅谈-编程知识网
extern _ExitProcess@4    ;in kernel32.dll
NASM、MASM浅谈-编程知识网

NASM、MASM浅谈-编程知识网global SayHello
NASM、MASM浅谈-编程知识网global _WinMain
NASM、MASM浅谈-编程知识网
NASM、MASM浅谈-编程知识网[SECTION .drectve info align=
8]
NASM、MASM浅谈-编程知识网    db 
" /subsystem:windows"
NASM、MASM浅谈-编程知识网    db 
" /out:sayhellon.exe"
NASM、MASM浅谈-编程知识网    db 
" /defaultlib:kernel32.lib"
NASM、MASM浅谈-编程知识网    db 
" /defaultlib:user32.lib"
NASM、MASM浅谈-编程知识网    db 
" /export:SayHello"
NASM、MASM浅谈-编程知识网    db 
" /entry:WinMain"
NASM、MASM浅谈-编程知识网    db 
" /merge:.rdata=.text",0
NASM、MASM浅谈-编程知识网
NASM、MASM浅谈-编程知识网[SECTION .text USE32 align=
16]
NASM、MASM浅谈-编程知识网
szTitle:
NASM、MASM浅谈-编程知识网    db 
"SayHello",0
NASM、MASM浅谈-编程知识网
szMsg: 
NASM、MASM浅谈-编程知识网    db 
"Hello World!"0
NASM、MASM浅谈-编程知识网
SayHello:
NASM、MASM浅谈-编程知识网    
push 0                ;uType
NASM、MASM浅谈-编程知识网
    push dword szTitle    ;lpCaption
NASM、MASM浅谈-编程知识网
    push dword szMsg      ;lpText
NASM、MASM浅谈-编程知识网
    push 0                ;hWnd
NASM、MASM浅谈-编程知识网
    call _MessageBoxA@16
NASM、MASM浅谈-编程知识网    
ret 16    
NASM、MASM浅谈-编程知识网
NASM、MASM浅谈-编程知识网
_WinMain:
NASM、MASM浅谈-编程知识网    
call SayHello
NASM、MASM浅谈-编程知识网    
push 0
NASM、MASM浅谈-编程知识网    
call _ExitProcess@4

     如上述代码所示,我基本上把link.exe连接器所需要的参数都写在源代码的.drectve段中了,注意:.drectve段由info标志,info是一种特殊的段,这个段只在coff文件中存在,link.exe连接器从这个段中读取控制指令参数,但是不会把这个段的内容写到生成的PE文件中。对info段的使用,MASM也用到了,只不过比较间接,比如对includelib的使用间接地使用info段,代码如下:

NASM、MASM浅谈-编程知识网;filename:sayhellom.asm
NASM、MASM浅谈-编程知识网;
cmd> ml /c /coff /nologo sayhellom.asm
NASM、MASM浅谈-编程知识网;
cmd> link /subsystem:windows /libpath:\masm32\lib 
NASM、MASM浅谈-编程知识网;
         /merge:.rdata=.text /export:SayHello /out:sayhellom.exe sayhellom.obj
NASM、MASM浅谈-编程知识网;
NASM、MASM浅谈-编程知识网
    .586
NASM、MASM浅谈-编程知识网    .model flat, stdcall
NASM、MASM浅谈-编程知识网    option 
casemap:none
NASM、MASM浅谈-编程知识网 
NASM、MASM浅谈-编程知识网    include windows.
inc
NASM、MASM浅谈-编程知识网    include kernel32.
inc
NASM、MASM浅谈-编程知识网    include user32.
inc
NASM、MASM浅谈-编程知识网 
NASM、MASM浅谈-编程知识网    includelib kernel32.lib
NASM、MASM浅谈-编程知识网    includelib user32.lib
NASM、MASM浅谈-编程知识网
NASM、MASM浅谈-编程知识网    public c SayHello
NASM、MASM浅谈-编程知识网
NASM、MASM浅谈-编程知识网.code
NASM、MASM浅谈-编程知识网
szTitle:
NASM、MASM浅谈-编程知识网    db 
"SayHello",0
NASM、MASM浅谈-编程知识网
szMsg:
NASM、MASM浅谈-编程知识网    db 
"Hello World!"0
NASM、MASM浅谈-编程知识网SayHello PROC C
NASM、MASM浅谈-编程知识网    
push MB_OK          ;uType
NASM、MASM浅谈-编程知识网
    push offset szTitle ;lpCaption
NASM、MASM浅谈-编程知识网
    push offset szMsg   ;lpText
NASM、MASM浅谈-编程知识网
    push 0              ;hWnd
NASM、MASM浅谈-编程知识网
    call [MessageBoxA]
NASM、MASM浅谈-编程知识网    
ret 16
NASM、MASM浅谈-编程知识网SayHello ENDP
NASM、MASM浅谈-编程知识网 
NASM、MASM浅谈-编程知识网
start:
NASM、MASM浅谈-编程知识网    
call SayHello
NASM、MASM浅谈-编程知识网    
push 0
NASM、MASM浅谈-编程知识网    
call [ExitProcess]
NASM、MASM浅谈-编程知识网end start
NASM、MASM浅谈-编程知识网
NASM、MASM浅谈-编程知识网

 

     上述两种方法生成的EXE程序都是1kb大小,虽然效果相同,但NASM将参数写在源代码中,比较便于管理和生成,虽然可以通过Makefile文件管理生成步骤,但仍然会多一个Makefile文件,还要多用一个make.exe或nmake.exe,呵呵,这只是我的个人之见,毕竟MASM社区众多,资源丰富,譬如头文件、现成的宏定义等比较丰富,不过,有兴趣的读者仍然可以尝试一下NASM的这一特性。

     NASM还有一种更加方便的外部库函数导入方法,就是import伪指令,import伪指令可以直接使用函数名,而不用给函数名加上'_'前缀和'@number'后缀,但import伪指令仅适合于OMF(borland obj)格式输出,OMF格式是MS在16位下操作系统的目标文件格式,borland仍然使用这种格式,并将格式进行了扩展,使得可以在Win32环境下使用,NASM支持这种扩展的OMF格式,但必须显式指定生成32位的obj。由于import伪指令需要OMF格式的支持,而MS的link.exe连接器会在连接时自动将OMF格式转换成COFF格式,从而无法完成导入外部标志的操作,因此,需要一个直接支持连接OMF格式的连接器,这里推荐开源连接器alink.exe。alink.exe连接器将根据import伪指令生成的连接信息,找到所需动态库,并自动导入外部函数符号,代码如下:

NASM、MASM浅谈-编程知识网;filename:sayhello.asm
NASM、MASM浅谈-编程知识网;
cmd> nasm -fobj -Xvc sayhello.asm
NASM、MASM浅谈-编程知识网;
cmd> alink -oPE -subsys windows sayhello.obj
NASM、MASM浅谈-编程知识网

NASM、MASM浅谈-编程知识网import MessageBoxA user32.dll
NASM、MASM浅谈-编程知识网extern MessageBoxA
NASM、MASM浅谈-编程知识网import ExitProcess kernel32.dll
NASM、MASM浅谈-编程知识网extern ExitProcess
NASM、MASM浅谈-编程知识网
NASM、MASM浅谈-编程知识网global SayHello
NASM、MASM浅谈-编程知识网export SayHello
NASM、MASM浅谈-编程知识网
NASM、MASM浅谈-编程知识网[SECTION CODE USE32 CLASS=CODE]
NASM、MASM浅谈-编程知识网
szTitle:
NASM、MASM浅谈-编程知识网    db 
"SayHello",0
NASM、MASM浅谈-编程知识网
szMsg: 
NASM、MASM浅谈-编程知识网    db 
"Hello World!"0
NASM、MASM浅谈-编程知识网
SayHello:
NASM、MASM浅谈-编程知识网    
push 0              ;uType
NASM、MASM浅谈-编程知识网
    push dword szTitle  ;lpCaption
NASM、MASM浅谈-编程知识网
    push dword szMsg    ;lpText
NASM、MASM浅谈-编程知识网
    push 0              ;hWnd
NASM、MASM浅谈-编程知识网
    call [MessageBoxA]
NASM、MASM浅谈-编程知识网    
ret 16
NASM、MASM浅谈-编程知识网 
NASM、MASM浅谈-编程知识网..
start:
NASM、MASM浅谈-编程知识网    
call SayHello
NASM、MASM浅谈-编程知识网    
push 0
NASM、MASM浅谈-编程知识网    
call [ExitProcess]
NASM、MASM浅谈-编程知识网
NASM、MASM浅谈-编程知识网

 

     上述代码段中的..start也是NASM针对OMF格式设计的程序入口简化标志,export伪指令生成的导出指令也将由alink.exe来执行。注意:alink.exe不支持段合并(至少我不知道如何使用alink.exe进行段合并>_<),因此,连接生成的EXE程序稍大一些,为2.51kb,有3个段,而上述另两种操作生成的EXE文件只有一个.text段。

转载于:https://www.cnblogs.com/antoniozhou/archive/2008/10/23/1318287.html