在 NASM 上组装时组装应用程序不起作用
Assembly application doesn't work when assembled on NASM
我目前正在研究 x86 汇编,我为 MASM 开发了一个简单的汇编应用程序,它调用函数 MessageBoxA 和 ExitProcess,这是源代码:
.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 制作等效代码,这就是我写的:
; 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
我正在为 link 库 User32.lib 和 kernel32.lib 使用 Microsoft 增量链接器,这是命令行:
nasm -f win32 test.asm -o test.obj
link /SUBSYSTEM:CONSOLE /Entry:main test.obj lib\User32.lib lib\kernel32.lib
问题是在 assemble 代码和 link obj 之后,生成的 .exe 文件不起作用,它显示错误消息 "test.exe has stopped working",有什么问题吗?
push DWORD [MsgTitle]
推送位于 MsgTitle
的前 4 个字节。您想要的是推送 MsgTitle
的地址,在 NASM 语法中将是 push DWORD MsgTtitle
。所以参数推送将变成:
push DWORD 0 ; MB_OK
push DWORD MsgTitle
push DWORD Message
push DWORD 0
另外,你的调用不正确。 __imp__MessageBoxA@16
本身不是 MessageBoxA
函数的地址,所以你需要一层间接:
call [__imp__MessageBoxA@16]
对ExitProcess
的调用也是如此。
或者,如果我将 __imp__MessageBoxA@16
更改为 _MessageBoxA@16
,我似乎可以使用 call _MessageBoxA@16
.
我目前正在研究 x86 汇编,我为 MASM 开发了一个简单的汇编应用程序,它调用函数 MessageBoxA 和 ExitProcess,这是源代码:
.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 制作等效代码,这就是我写的:
; 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
我正在为 link 库 User32.lib 和 kernel32.lib 使用 Microsoft 增量链接器,这是命令行:
nasm -f win32 test.asm -o test.obj
link /SUBSYSTEM:CONSOLE /Entry:main test.obj lib\User32.lib lib\kernel32.lib
问题是在 assemble 代码和 link obj 之后,生成的 .exe 文件不起作用,它显示错误消息 "test.exe has stopped working",有什么问题吗?
push DWORD [MsgTitle]
推送位于 MsgTitle
的前 4 个字节。您想要的是推送 MsgTitle
的地址,在 NASM 语法中将是 push DWORD MsgTtitle
。所以参数推送将变成:
push DWORD 0 ; MB_OK
push DWORD MsgTitle
push DWORD Message
push DWORD 0
另外,你的调用不正确。 __imp__MessageBoxA@16
本身不是 MessageBoxA
函数的地址,所以你需要一层间接:
call [__imp__MessageBoxA@16]
对ExitProcess
的调用也是如此。
或者,如果我将 __imp__MessageBoxA@16
更改为 _MessageBoxA@16
,我似乎可以使用 call _MessageBoxA@16
.