2016-10-12 17 views
-1

私は現在、NASM 2.12.01とGCC 4.8.1をリンカとして使用して、いくつかのWindowsネイティブアセンブリをプログラミングしています。Win32アセンブリ - コンソールへのWriteFile()は出力を表示しません

しかし、この単純なHelloWorldプログラムは、苦情なしで&リンクをコンパイルしますが、コンソール画面に何も出力しません。

GetStdHandleは、現在のコンソールに有効なハンドルを返さないため、出力が表示されないようです。

しかし、問題がある可能性があります。

コード:

; Name:  hello.asm 
; Assemble: nasm.exe -fwin32 hello.asm 
; Link:  gcc -mwindows -o hello hello.obj -lkernel32 -lmsvcrt 
; Run:  a.exe 

BITS 32 
extern [email protected] 
extern [email protected] 
extern [email protected] 
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 [email protected] 

; 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 [email protected] 

; 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 [email protected] 
+0

* "問題は他にもあるかもしれません。" * - 推測を止めるためにのみエラー処理を実装してみませんか? – IInspectable

+0

@IInspectableそして、あなたはこんにちは世界のASMプログラムでそれをどのように実装しますか? – hakeris1010

+0

プロセスが行うすべてのシステムコールをトレースできるWindowsツールはありますか? Linux/Unixでは、 'strace'はこれをデバッグするのに最適です。 ([このランダムブログの投稿の例の出力](http://www.thegeekstuff.com/2011/11/strace-examples)を参照)。 –

答えて

1

コンソールアプリケーションを生成するには、GCCに対して-mconsoleオプションを使用する必要があります。オンラインドキュメントsection 3.18.55, x86 Windows Optionsを参照してください。

GUIアプリケーションを作成する-mwindowsを使用しています。 GUIアプリケーションを起動するとき、Windowsはコンソールを作成せず、標準ハンドルを設定しません。

+0

うわー!これはまさに問題の原因です!単純に作成するコンソールハンドルはありませんでした。 – hakeris1010

0

あなたは正しくスタックフレームを設定することはありません!

これは適切な方法ではありません。

push ebp 
sub esp, 4 

あなたは何かが欠けていますか?あなたのスタックが台無しです!

prolougeは次のようになります。

push ebp 
    mov ebp, esp 
    sub esp, 4 

epilougeについては、まさにそれを逆に。

+0

ベースポインタを特定の値に設定する必要はありません。地元の人々や議論にもっと簡単にアクセスできるのは純粋に便利なことです。実際、フレームポインタを省略することは、高水準言語コンパイラにとって非常に一般的な最適化の1つです。私は申し訳ありませんが、これは質問に答えません(私は誰がこれを投票したのか、なぜこれを投票したのか分かりません)。 – IInspectable

関連する問題