NASM与link、golink和alink具体例子使用对比

一、OMF文件格式链接:使用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伪指令生成的连接信息,找到所需动态库,并自动导入外部函数符号。..start也是NASM针对OMF格式设计的程序入口简化标志,export伪指令生成的导出指令也将由alink.exe来执行。注意:alink.exe不支持段合并(至少我不知道如何使用alink.exe进行段合并>_<),因此,连接生成的EXE程序稍大一些,为2.51kb,有3个段,而上述另两种操作生成的EXE文件只有一个.text段。
1、32位程序例子:
;filename:obj32.asm
import MessageBoxA user32.dll
extern MessageBoxA
import ExitProcess kernel32.dll
extern ExitProcess

global obj32
export obj32

[SECTION CODE USE32 CLASS=CODE]
szTitle:
    db "SayHello",0
szMsg:
    db "Hello World!", 0
obj32:
    push 0              ;uType
    push dword szTitle  ;lpCaption
    push dword szMsg    ;lpText
    push 0              ;hWnd
    call [MessageBoxA]
    ret 16
 
..start:
    call obj32
    push 0
    call [ExitProcess]

使用alink。
cmd> nasm -fobj obj32.asm
cmd> alink -oPE  obj32.obj

2、16位程序例子:
;filename:obj16.asm
segment code  use16
str1: db "name$"

segment data use16
..start:
mov ax,code
mov ds,ax
mov dx,str1
mov ah,9
int 21h
mov ah,4ch
int 21h

使用alink。
cmd> nasm -fobj obj16.asm
cmd> alink obj16.obj 或alink -oEXE obj16.obj

二、微软Win32平台的coff文件格式链接:这种文件格式可以被MS的link.exe连接器连接成PE文件。通常,我们知道MASM可以通过includelib伪指令将导入库的名称传给连接器link.exe,告知它该从哪个库中导入所需外部符号,而NASM汇编器在这方面的能力却是有过之而无不及,它可以通过info段,将更多的连接参数传递给link.exe,链接时要加入口名。link.exe连接器所需要的参数都写在源代码的.drectve段中了,注意:.drectve段由info标志,info是一种特殊的段,这个段只在coff文件中存在,link.exe连接器从这个段中读取控制指令参数,但是不会把这个段的内容写到生成的PE文件中。对info段的使用,MASM也用到了,只不过比较间接,比如对includelib的使用间接地使用info段。
1、使用微软link.exe与kernel32.lib、user32.lib。例子如下:
;filename: win32sam.asm

extern __imp__MessageBoxA@16    ;in user32.dll   注解:可改为__imp__MessageBoxA@16(使用微软的库)或__imp_MessageBoxA@16(或MessageBoxA使用win32.lib库,使用什么外部名,要与链接库里的名称相符,nasm不会对外部符号进行增加东西,ml编译器在编译时则会对外部符号加_与@**。
extern _ExitProcess@4    ;in kernel32.dll

global SayHello
global _main

[SECTION .drectve info align=8]
    db " /subsystem:windows"
    db " /out: win32sam.exe"
    db " /defaultlib:kernel32.lib"
    db " /defaultlib:user32.lib"
    db " /export:SayHello"
    db " /entry:main"
    db " /merge:.rdata=.text",0

[SECTION .text USE32 align=16]
szTitle:
    db "SayHello",0
szMsg:
    db "Hello World!", 0
SayHello:
    push 0                ;uType
    push dword szTitle    ;lpCaption
    push dword szMsg      ;lpText
    push 0                ;hWnd
    call [__imp__MessageBoxA@16]
    ret 16   

_main:
    call SayHello
    push 0
    call _ExitProcess@4

使用link.exe与kernel32.lib、user32.lib链接命令如下:
cmd> nasm -fwin32 win32sam.asm
cmd> link  win32sam.obj

 

2、使用golink。例子如下:
;filename: win32sam.asm

extern __imp__MessageBoxA@16    ;in user32.dll   或是__imp_MessageBoxA@16
extern _ExitProcess@4    ;in kernel32.dll

global SayHello
global _main


[SECTION .text USE32 align=16]
szTitle:
    db "SayHello",0
szMsg:
    db "Hello World!", 0
SayHello:
    push 0                ;uType
    push dword szTitle    ;lpCaption
    push dword szMsg      ;lpText
    push 0                ;hWnd
    call [__imp__MessageBoxA@16] ;  或是__imp_MessageBoxA@16
    ret 16    

_main:
    call SayHello
    push 0
    call _ExitProcess@4

使用链接命令如下:
cmd> nasm -fwin32 -o win32sam.obj win32sam.asm
cmd> GoLink.exe /entry _main win32sam.obj kernel32.dll user32.dll

 

3、使用alink.exe与win32.lib。例子如下:
;filename: win32sam.asm

extern __imp_MessageBoxA    ;in user32.dll   
extern ExitProcess    ;in kernel32.dll

global SayHello
global _main

[SECTION .text USE32 align=16]
szTitle:
    db "SayHello",0
szMsg:
    db "Hello World!", 0
SayHello:
    push 0                ;uType
    push dword szTitle    ;lpCaption
    push dword szMsg      ;lpText
    push 0                ;hWnd
    call [__imp_MessageBoxA]
    ret 16   

_main:
    call SayHello
    push 0
    call ExitProcess

链接命令如下:
cmd> nasm -fwin32  win32sam.asm
cmd> alink -oPE -entry _main win32sam.obj win32.lib

三、标准coff文件格式链接:这种文件格式不支持info字段,不支持align对齐:
1、使用微软link.exe与kernel32.lib、user32.lib。例子如下:
;filename: win32sam.asm

extern __imp__MessageBoxA@16    ;in user32.dll 
extern _ExitProcess@4    ;in kernel32.dll

global SayHello
global _main

[SECTION .text USE32]
szTitle:
    db "SayHello",0
szMsg:
    db "Hello World!", 0
SayHello:
    push 0                ;uType
    push dword szTitle    ;lpCaption
    push dword szMsg      ;lpText
    push 0                ;hWnd
    call [__imp__MessageBoxA@16]
    ret 16   

_main:
    call SayHello
    push 0
    call _ExitProcess@4

链接命令如下:
cmd>nasm -f coff -o win32sam.obj win32sam.asm
cmd>link /subsystem:windows /defaultlib:kernel32.lib /defaultlib:user32.lib /export:SayHello /entry:main win32sam.obj

2、使用golink。例子如下:
;filename: win32sam.asm

extern __imp__MessageBoxA@16    ;in user32.dll  或是__imp_MessageBoxA@16
extern __imp__ExitProcess@4    ;in kernel32.dll 或是__imp__ExitProcess@4

global SayHello
global _main


[SECTION .text USE32 ]
szTitle:
    db "SayHello",0
szMsg:
    db "Hello World!", 0
SayHello:
    push 0                ;uType
    push dword szTitle    ;lpCaption
    push dword szMsg      ;lpText
    push 0                ;hWnd
    call [__imp__MessageBoxA@16]  ;或是__imp_MessageBoxA@16
    ret 16   

_main:
    call SayHello
    push 0
    call [__imp__ExitProcess@4]  ;或是__imp_MessageBoxA@16

使用链接命令如下:
cmd> nasm -fcoff  -o win32sam.obj win32sam.asm
cmd> GoLink.exe /entry _main win32sam.obj kernel32.dll user32.dll


========================================================
3、使用alink.exe与win32.lib。例子如下:
;filename: win32sam.asm

extern __imp_MessageBoxA    ;in user32.dll   
extern __imp_ExitProcess    ;in kernel32.dll

global SayHello
global _main

[SECTION .text USE32]
szTitle:
    db "SayHello",0
szMsg:
    db "Hello World!", 0
SayHello:
    push 0                ;uType
    push dword szTitle    ;lpCaption
    push dword szMsg      ;lpText
    push 0                ;hWnd
    call [__imp_MessageBoxA]
    ret 16   

_main:
    call SayHello
    push 0
    call [__imp_ExitProcess]

链接命令如下:
cmd> nasm -fcoff -o win32sam.obj  win32sam.asm ?
cmd> alink -oPE -entry _main win32sam.obj win32.lib

你可能感兴趣的:(NASM与link、golink和alink具体例子使用对比)