2012-09-25 10 views
5

Sto usando nasm per compilare il seguente assembly. Tuttavia il codice si blocca nella console sotto Windows.Hello world using nasm in windows assembly

C: \> nasm -f win32 test.asm -o test.o

C: \> ld test.o -o test.exe

section .data 
    msg db 'Hello world!', 0AH 
    len equ $-msg 

section .text 
    global [email protected] 

[email protected]: 
    mov edx, len 
    mov ecx, msg 
    mov ebx, 1 
    mov eax, 4 
    int 80h 

    mov ebx, 0 
    mov eax, 1 
    int 80h 

Secondo questo post. La funzione main non è disponibile in Windows e deve essere sostituita da WinMain.

Così, se il punto di ingresso è _start o main, dovrebbe essere cambiato per [email protected] e cambiare il ret al termine della procedura di ret 16:

Il mio esempio di lavoro:

section .text  
global [email protected]  

[email protected]:  
mov eax, 0  
ret 16 
+3

Si prega di modificare il titolo in modo che sarà utile per i visitatori futuri. Altrimenti potrebbe essere chiuso come troppo localizzato. –

+0

@RaymondChen a cosa? – fuzz

risposta

21

Il più grande il problema è che stai cercando di usare interruzioni di Linux su Windows! int 80 NON funzionerà su Windows.

Utilizziamo Assembly, quindi il punto di ingresso può essere QUALSIASI etichetta desiderata. Il punto di ingresso standard che ld cerca è _start, se si desidera utilizzare un'altra etichetta, è necessario indicare ld con l'opzione -e Quindi, se volete che il vostro marchio di partenza per essere principale, quindi è necessario

global main 
ld -e main test.o -o test.exe 

Se si utilizzerà NASM su Windows, si consiglia di utilizzare GoLink come linker. Ecco una semplice console app finestre:

STD_OUTPUT_HANDLE equ -11 
NULL    equ 0 

global GobleyGook 
extern ExitProcess, GetStdHandle, WriteConsoleA 

section .data 
msg     db "Hello World!", 13, 10, 0 
msg.len    equ $ - msg 

section .bss 
dummy    resd 1 

section .text 
GobleyGook: 
    push STD_OUTPUT_HANDLE 
    call GetStdHandle 

    push NULL 
    push dummy 
    push msg.len 
    push msg 
    push eax 
    call WriteConsoleA 

    push NULL 
    call ExitProcess 

makefile:

hello: hello.obj 
    GoLink.exe /console /entry GobleyGook hello.obj kernel32.dll 

hello.obj: hello.asm 
    nasm -f win32 hello.asm -o hello.obj 
+0

Esattamente quello che stavo cercando, grazie. – fuzz

+0

@Gunner grazie. Una domanda però - qual è la ragione per cui raccomandi GoLink su altri linker? –

+0

@Boris Preferenza personale credo. Ho trovato più facile lavorare con altri linker su Windows. – Gunner

5

Anche se, questo stesso programma probabilmente verrà eseguito in vino su Linux come un fascino. :)

WINE non impedisce l'utilizzo di chiamate di sistema Linux da binari di Windows PE; le istruzioni della macchina vengono eseguite in modo nativo e WINE fornisce solo funzioni DLL.

+0

Buono a sapersi, grazie. – fuzz

+4

@JayBlanchard Questa è una risposta, perché indica il sistema operativo, in cui il programma funzionerà correttamente, senza menzionare nella domanda di arresto anomalo. – johnfound

+0

Oh, intendi su una macchina Linux, dove le chiamate di sistema vengono eseguite in modo nativo e WINE non ha nulla a che fare con esse.All'inizio pensavo che intendessi che WINE andava in entrambe le direzioni, e che poteva emulare l'ABI 'int 0x80' di Linux su una macchina Windows! –