2016-10-12 5 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 도구가 있습니까? 리눅스/유닉스에서'strace'는 이런 것들을 디버깅하는데 아주 좋습니다. ([이 임의의 블로그 게시물의 예제 출력] (http://www.thegeekstuff.com/2011/11/strace-examples) 참조). –

답변

1

콘솔 응용 프로그램을 생성하려면 GCC에 -mconsole 옵션을 사용해야합니다. 온라인 설명서 section 3.18.55, x86 Windows Options을 참조하십시오.

GUI 응용 프로그램을 만드는 -mwindows을 사용하고 있습니다. Windows는 GUI 응용 프로그램을 시작할 때 콘솔을 만들거나 표준 핸들을 설정하지 않습니다.

+0

와우! 이것은 정확히 문제가 무엇입니까! 생성 할 콘솔 핸들이 없었습니다. – hakeris1010

0

올바르게 스택 프레임을 설정하지!

이 적절한 방법이 아니다 :

push ebp 
sub esp, 4 

당신이 뭔가를 놓치고 있습니까? 스택이 엉망입니다!

prolouge는해야 다음 epilouge를 들어

push ebp 
    mov ebp, esp 
    sub esp, 4 

, 그냥 역.

+0

기본 포인터를 특정 값으로 설정할 필요가 없습니다. 지역 주민과 논쟁에보다 쉽게 ​​접근 할 수있는 것은 단지 편의입니다. 사실, 프레임 포인터를 생략하는 것은 모든 고수준 언어 컴파일러에 대한 매우 일반적인 최적화 중 하나입니다. 미안하지만 질문에 답할 수 없습니다 (이 질문에 누가 득표 한 것인지, 왜 그 이유를 모르겠습니다). – IInspectable