NASM Konsolenausgabe mit GetStdHandle, WriteFile & CloseHandle
-
Hallo zusammen,
ich übe mich gerade ein wenig in WIN32-Assembler und benutze den NASM. In meinem Programm hole ich mir das stdout-Handle mittels GetStdHandle() und möchte mit WriteFile() die Nachricht "Hello World!" in der Windows-Konsole ausgeben. Anschließend soll das Handle mit CloseHandle() geschlossen werden. Leider macht mein Programm gar nichts, stürzt aber auch nicht ab
EXTERN GetStdHandle IMPORT GetStdHandle kernel32.dll EXTERN WriteFile IMPORT WriteFile kernel32.dll EXTERN CloseHandle IMPORT CloseHandle kernel32.dll EXTERN ExitProcess IMPORT ExitProcess kernel32.dll SECTION data PUBLIC USE32 class='DATA' Msg dd "Hello World!", 0 SECTION bss PUBLIC USE32 class='BSS' stdout resd 1 ; stdout file handle count resd 1 ; number of bytes written ..start: push dword -11 ; get stdout handle call [GetStdHandle] mov [stdout], eax push dword 0 ; lpOverlapped = NULL push dword count ; lpNumberOfBytesWritten push dword 13 ; nNumberOfBytesToWrite push dword Msg ; lpBuffer push dword [stdout] ; hFile call [WriteFile] push stdout ; close handle call [CloseHandle] push dword 0 ; exit program call [ExitProcess]
Hat jemand vielleicht einen Tipp für mich?
Gruß,
Lord Kefir
-
Sieht so weit eigentlich ok aus.
Also: Wie assemblierst und linkst du dein Programm genau? Wie rufst du es auf?
-
nasm.exe -fobj ff.asm ALINK.EXE -oPE ff.obj win32.lib
Gruß,
Lord Kefir
-
Ok, da duerfte das Problem liegen:
Entweder musst du dein Programm als Win32-Konsolenanwendung linken (siehe Hilfe-Text des Linkers), dann wird automatisch beim Start ein Konsolenfenster fuer dein Programm erzeugt, oder du muesstest dir erstmal selbst ein Konsolenfenster erstellen (siehe msdn). Ich denke 1. Variante ist zweckmaessiger.
Dann hoffe ich, dass du dein Programm auch aus der Win32-Konsole heraus aufrufst (also nicht per Doppelklick o.Ae.!). Sonst siehst du das Fenster nur kurz aufflackern.Zuletzt noch: Nach einiger Arbeit mit dem Gespann nasm + alink bin ich zu dem Schluss, gekommen, dass alink ... leider recht unbrauchbar ist. Verbugged und wird offenbar nicht mehr weiter entwickelt.
Stattdessen wuerde ich zB. GoLink empfehlen. Klein, schnell und braucht vor allem diese nervigen Libs nicht.
Dabei wuerde ich dann auch im Asm-Code die "IMPORT"s sowie die eckigen Klammern um die Funktionsaufrufe weglassen.[edit]Fast vergessen:
obj ist das Format fuer "MS-DOS 16-bit/32-bit OMF object files". Nimm vielleicht besser win 32: "win32 Microsoft Win32 (i386) object files".
Dann funktioniert aber "..start" nicht mehr. Stattdessen musst du dann dein Start-Label "global" machen, also irgendwo in deinen Code "global start" packen, wenn dein Start-Label "start" heisst. Zusaetzlich musst du dann noch dem Linker dieses Label als Einstiegsadresse angeben.
[/edit]
-
Danke für den Tipp, GoLink ist super.
Das ist aber auch kompliziert mit den ganzen Executables unter WIN32 (bin eigentlich ELF gewöhnt ;)).
Gruß,
Lord Kefir
-
Nur zur Ergaenzung:
Ich habe das gerade nochmal ausprobiert und das Erstellen muesste auch so gehen, wie Lord Kefir das zuerst angegeben (also mit -fobj, EXTERN und IMPORT, ..start und alink) hat. Scheinbar sogar ohne die win32.lib.