2016-10-12 14 views
-1

Я сейчас программирую некоторую родную сборку Windows, используя NASM 2.12.01 и GCC 4.8.1 в качестве компоновщика.Win32 Assembly - 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

@Инспективный И как именно вы его реализуете в программе ASM Hello World? – hakeris1010

+0

Есть ли инструмент Windows, который может отслеживать все системные вызовы, которые делает процесс? В Linux/Unix «strace» отлично подходит для отладки таких вещей. (См. [Пример вывода в этом случайном блоге] (http://www.thegeekstuff.com/2011/11/strace-examples)). –

ответ

1

Для создания консольного приложения вы должны использовать опцию -mconsole для GCC. См. Онлайн-документацию, section 3.18.55, x86 Windows Options.

Вы используете -mwindows, который создает графическое приложение. Windows не создает консоль или не устанавливает стандартные дескрипторы при запуске приложений GUI.

+0

Вау! Именно в этом и была проблема! Просто не было никаких консольных ручек для создания! – hakeris1010

0

Вы никогда не настраивали кадр стека правильно!

Это не правильный способ:

push ebp 
sub esp, 4 

Вы не нашли что-нибудь? Ваш стек перепутался!

prolouge должно быть:

push ebp 
    mov ebp, esp 
    sub esp, 4 

Для epilouge, только обратное, что.

+0

Нет необходимости устанавливать базовый указатель на какое-либо конкретное значение. Это просто удобство, более легкий доступ к местным жителям, а также к аргументам. Фактически, опускание указателя кадра является одной из самых распространенных оптимизаций для любого компилятора языка высокого уровня. Извините, но это не отвечает на вопрос (я не знаю, кто это проголосовал или почему). – IInspectable