Win32 程序集 - WriteFile() 到控制台不显示输出
Win32 Assembly - WriteFile() to console don't show output
我现在正在编写一些 Windows 本机程序集,使用 NASM 2.12.01 和 GCC 4.8.1 作为链接器。
但是,这个简单的 HelloWorld 程序编译和链接没有任何问题,但不会向控制台屏幕输出任何内容。
似乎 GetStdHandle
不是 return 当前控制台的有效句柄,因此没有显示输出。
但问题可能是其他的。
代码:
; Name: hello.asm
; Assemble: nasm.exe -fwin32 hello.asm
; Link: gcc -mwindows -o hello hello.obj -lkernel32 -lmsvcrt
; Run: a.exe
BITS 32
extern _GetStdHandle@4
extern _WriteFile@20
extern _ExitProcess@4
extern __getch
extern _puts
SECTION .data
str: db `Hello world!\n` ; C-like strings in NASM with backticks
strlen equ $-str
pause: db "Do you know where the ANY key is? :-)",0
SECTION .text
GLOBAL _main
_main:
; Stack frame for NumberOfBytesWritten
push ebp
sub esp, 4
; http://msdn.microsoft.com/en-us/library/windows/desktop/ms683231.aspx
; HANDLE WINAPI GetStdHandle(
; _In_ DWORD nStdHandle
; );
push -11
call _GetStdHandle@4
; http://msdn.microsoft.com/en-us/library/windows/desktop/aa365747.aspx
; BOOL WINAPI WriteFile(
; _In_ HANDLE hFile,
; _In_ LPCVOID lpBuffer,
; _In_ DWORD nNumberOfBytesToWrite,
; _Out_opt_ LPDWORD lpNumberOfBytesWritten,
; _Inout_opt_ LPOVERLAPPED lpOverlapped
; );
push 0 ; lpOverlapped,
lea ebx, [ebp-4] ; EBX: address of NumberOfBytesWritten
push ebx ; lpNumberOfBytesWritten,
push strlen ; nNumberOfBytesToWrite
push str ; lpBuffer,
push eax ; hFile (result from GetStdHandle
call _WriteFile@20
; msvcrt.dll (C library)
push pause
call _puts ; http://msdn.microsoft.com/library/tf52y4t1.aspx
add esp, 4
call __getch ; http://msdn.microsoft.com/library/078sfkak.aspx
; ExitProcess (0)
push 0
call _ExitProcess@4
您从未正确设置栈帧!
这不是正确的方法:
push ebp
sub esp, 4
你是不是漏了什么?你的堆栈搞砸了!
开场白应该是:
push ebp
mov ebp, esp
sub esp, 4
对于尾声,只需将其反转即可。
为了生成控制台应用程序,您必须使用 GCC 的 -mconsole
选项。请参阅联机文档,section 3.18.55, x86 Windows Options。
您正在使用 -mwindows
创建 GUI 应用程序。 Windows 启动 GUI 应用程序时不创建控制台或设置标准句柄。
我现在正在编写一些 Windows 本机程序集,使用 NASM 2.12.01 和 GCC 4.8.1 作为链接器。
但是,这个简单的 HelloWorld 程序编译和链接没有任何问题,但不会向控制台屏幕输出任何内容。
似乎 GetStdHandle
不是 return 当前控制台的有效句柄,因此没有显示输出。
但问题可能是其他的。
代码:
; Name: hello.asm
; Assemble: nasm.exe -fwin32 hello.asm
; Link: gcc -mwindows -o hello hello.obj -lkernel32 -lmsvcrt
; Run: a.exe
BITS 32
extern _GetStdHandle@4
extern _WriteFile@20
extern _ExitProcess@4
extern __getch
extern _puts
SECTION .data
str: db `Hello world!\n` ; C-like strings in NASM with backticks
strlen equ $-str
pause: db "Do you know where the ANY key is? :-)",0
SECTION .text
GLOBAL _main
_main:
; Stack frame for NumberOfBytesWritten
push ebp
sub esp, 4
; http://msdn.microsoft.com/en-us/library/windows/desktop/ms683231.aspx
; HANDLE WINAPI GetStdHandle(
; _In_ DWORD nStdHandle
; );
push -11
call _GetStdHandle@4
; http://msdn.microsoft.com/en-us/library/windows/desktop/aa365747.aspx
; BOOL WINAPI WriteFile(
; _In_ HANDLE hFile,
; _In_ LPCVOID lpBuffer,
; _In_ DWORD nNumberOfBytesToWrite,
; _Out_opt_ LPDWORD lpNumberOfBytesWritten,
; _Inout_opt_ LPOVERLAPPED lpOverlapped
; );
push 0 ; lpOverlapped,
lea ebx, [ebp-4] ; EBX: address of NumberOfBytesWritten
push ebx ; lpNumberOfBytesWritten,
push strlen ; nNumberOfBytesToWrite
push str ; lpBuffer,
push eax ; hFile (result from GetStdHandle
call _WriteFile@20
; msvcrt.dll (C library)
push pause
call _puts ; http://msdn.microsoft.com/library/tf52y4t1.aspx
add esp, 4
call __getch ; http://msdn.microsoft.com/library/078sfkak.aspx
; ExitProcess (0)
push 0
call _ExitProcess@4
您从未正确设置栈帧!
这不是正确的方法:
push ebp
sub esp, 4
你是不是漏了什么?你的堆栈搞砸了!
开场白应该是:
push ebp
mov ebp, esp
sub esp, 4
对于尾声,只需将其反转即可。
为了生成控制台应用程序,您必须使用 GCC 的 -mconsole
选项。请参阅联机文档,section 3.18.55, x86 Windows Options。
您正在使用 -mwindows
创建 GUI 应用程序。 Windows 启动 GUI 应用程序时不创建控制台或设置标准句柄。