在NASM上组装时,组装应用程序不起作用

Assembly application doesn't work when assembled on NASM

我目前正在研究x86汇编,我为MASM开发了一个简单的汇编应用程序,该应用程序调用了MessageBoxA和ExitProcess函数,这是源代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
.386
.model flat, stdcall
option casemap:none

includelib C:\\masm\\masm32\\lib\\kernel32.lib
includelib C:\\masm\\masm32\\lib\\user32.lib

ExitProcess PROTO :DWORD
MessageBoxA PROTO :DWORD,:DWORD,:DWORD,:DWORD

.data

msg db"Hello There!!", 0
cpt db"My First Programm!!", 0

.code

start:
    push 0   ; MB_OK
    push OFFSET cpt  ; title
    push OFFSET msg  ; msg
    push 0    ; HWND
    call MessageBoxA

    push 0
    call ExitProcess

end start

上面的代码在MASM上工作正常,但是现在我正在尝试为NASM创建等效的代码,这就是我写的内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
; test.asm
SECTION .DATA
MsgTitle: db"Message", 10, 0
Message: db"Hello There!", 10, 0

SECTION .TEXT

EXTERN __imp__MessageBoxA@16
EXTERN __imp__ExitProcess@4
GLOBAL _main

_main: ; int main()
    push ebp
    mov ebp, esp
    ;;; Function Main Content
    ; MessageBoxA(NULL,"Hello There!","Message", MB_OK);
    push 0 ; MB_OK
    push DWORD [MsgTitle]
    push DWORD [Message]
    push 0
    call __imp__MessageBoxA@16
    ; ExitProcess(0)
    push DWORD 0
    call __imp__ExitProcess@4
    ;;;
    mov esp, ebp
    pop ebp
    ;;
    mov eax, 0
    ret

我正在使用Microsoft增量链接器链接库User32.lib和kernel32.lib,这是命令行:

1
2
nasm -f win32 test.asm -o test.obj
link /SUBSYSTEM:CONSOLE /Entry:main test.obj lib\\User32.lib lib\\kernel32.lib

问题是在汇编代码并链接obj之后,生成的.exe文件不起作用,它显示错误消息" test.exe已停止工作",这是怎么回事?


push DWORD [MsgTitle]将位于MsgTitle的前4个字节压入。您要推送的地址为MsgTitle,在NASM语法中为push DWORD MsgTtitle。因此推入的参数将变为:

1
2
3
4
push DWORD 0 ; MB_OK
push DWORD MsgTitle
push DWORD Message
push DWORD 0

此外,您的通话不正确。 __imp__MessageBoxA@16本身不是MessageBoxA函数的地址,因此您需要一个间接级别:

1
call [__imp__MessageBoxA@16]

ExitProcess的调用也是如此。

或者,如果我将__imp__MessageBoxA@16更改为_MessageBoxA@16,则似乎可以使用call _MessageBoxA@16