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.


Anmelden zum Antworten