2012-09-25 70 views
5

Estoy usando nasm para compilar el siguiente ensamblaje. Sin embargo, el código se bloquea en la consola en Windows.Hola mundo usando nasm en ensamblaje de Windows

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 

Según esto post. La función main no está disponible en Windows y debe reemplazarse por WinMain.

Así que si su punto de entrada es _start o main, se debe cambiar a [email protected] y cambiar el ret al final del procedimiento de ret 16:

Mi ejemplo de trabajo:

section .text  
global [email protected]  

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

Por favor, edite el título para que sea útil para los futuros visitantes. De lo contrario, puede cerrarse como demasiado localizado. –

+0

@RaymondChen a qué? – fuzz

Respuesta

21

El mayor ¡El problema es que estás tratando de usar interrupciones de Linux en Windows! int 80 NO funcionará en Windows.

Estamos utilizando Asamblea, por lo que su punto de entrada puede ser CUALQUIER etiqueta que desee. El punto de entrada estándar que ld busca es _start, si desea utilizar otra etiqueta, es necesario contar con la opción ld -e Así que si usted quiere que su etiqueta de principio a ser principal, entonces usted necesita

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

Si va a utilizar NASM en Windows, recomendaré utilizar GoLink como su enlazador. Aquí es una sencilla aplicación de consola de Windows:

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

Exactamente lo que buscaba, gracias. – fuzz

+0

@Gunner gracias. Sin embargo, una pregunta: ¿cuál es la razón por la que recomienda GoLink sobre otros vinculadores? –

+0

@Boris Preferencia personal, supongo. Encontré que es más fácil trabajar con él que con otros enlazadores en Windows. – Gunner

5

Si bien, este mismo programa, probablemente se ejecutará en el vino en Linux como un encanto. :)

WINE no impide el uso de llamadas al sistema Linux desde binarios de Windows PE; las instrucciones de la máquina se ejecutan de forma nativa y WINE solo proporciona funciones de DLL.

+0

Es bueno saberlo, gracias. – fuzz

+4

@JayBlanchard Esta es una respuesta, porque señala el sistema operativo, donde el programa funcionará correctamente, sin mencionar en el bloqueo de la pregunta. – johnfound

+0

Ah, se refiere a una máquina Linux, donde las llamadas al sistema se ejecutan de forma nativa y WINE no tiene nada que ver con ellas.¡Al principio pensé que querías decir que WINE funcionaba en ambos sentidos, y que podía emular el ABI Linux 'int 0x80' en una máquina con Windows! –

Cuestiones relacionadas