nasm 未在 Windows 8 中执行文件

nasm is not executing file in Windows 8

最近开始学习汇编,所以我对此比较陌生。我们在学校使用 Linux,但我想尝试在我的 PC 上编码。我在 Win8.1 64 位系统上使用 nasm。

代码如下:

section .text
    global _WinMain@16

_WinMain@16:
    mov edx, len
    mov ecx, msg
    mov ebx, 1
    mov eax, 4
    ret 16

    mov eax, 1
    ret 16

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

nasm 似乎是 运行ning 因为它响应命令,但它不执行程序:

如何运行程序?代码有问题还是系统兼容性?我最后的选择是安装 Ubuntu.

我将从 returning 开始。

main.asm

[section] .text
    global _main

_main:
        mov eax, 6
        ret         ; returns eax (exits)

这个程序所做的只是return 6.

Assemble 和 link 像这样:

c:\Users\James\Desktop>nasm -fwin32 main.asm

c:\Users\James\Desktop>ld -e _main main.obj -o main.exe

c:\Users\James\Desktop>main.exe

c:\Users\James\Desktop>echo %errorlevel%
6

使用栈帧。

main.asm

[section] .text
    global _main

_main:
        push    ebp     ; set up stack frame
        mov     ebp,esp

        push 6          
        pop eax;        ; mov 6 into eax using the stack

        leave           ; destroy stack frame
        ret             ; return eax

正在编译:

c:\Users\James\Desktop>nasm -fwin32 main.asm

c:\Users\James\Desktop>ld -e _main main.obj -o main.exe

c:\Users\James\Desktop>main

c:\Users\James\Desktop>echo %errorlevel%
6

要使用您自己的外部函数,您需要:

func.asm

[section] .text
    global _func

_func:
        push ebp        ; set up stack frame
        mov  ebp,esp

        mov eax, [ebp+8] ; move argument into eax
        add eax, 3       ; eax = eax + 3

        leave           ; destroy stack frame
        ret             ; return to caller with (eax + 3)

main.asm

[section] .text
    global _main

extern _func

_main:
        push    ebp     ; set up stack frame
        mov     ebp,esp

        push 3          ; push argument onto stack for function
        call _func      ; calling the function
        add esp, 4      ; clean 1 argument

        leave           ; destroy stack frame
        ret             ; return what func returned in eax

正在编译:

c:\Users\James\Desktop>nasm -fwin32 func.asm

c:\Users\James\Desktop>nasm -fwin32 main.asm

c:\Users\James\Desktop>ld -e _main main.obj func.obj -o main.exe

c:\Users\James\Desktop>main

c:\Users\James\Desktop>echo %errorlevel%
6

我很确定你的代码不是 ret 16,你的意思是 int 80h

如果是这样,您将无法像在 linux 中那样在 windows 中进行系统调用, 但是你可以使用 gcc 到 link 和 c's 库函数,例如; stdio's puts.

要使用 c 库函数,例如 printfputs,您可以这样做:

 [section] .text
    global _main

    extern _puts

    _main:
            push ebp        ; set up stack frame
            mov ebp,esp

            push helloStr   ; push argument onto stack for function
            call _puts      ; calling the function
            add esp, 4      ; clean 1 argument

            mov eax, 0
            leave           ; destroy stack frame
            ret             ; return 0 (exit)

[section] .data
    helloStr    db  "Hello World!",0

而不是使用 ld(因为参数很难正确), 您可以像使用普通 c 源文件一样在 obj 文件上使用 gcc

c:\Users\James\Desktop>nasm -fwin32 main.asm

c:\Users\James\Desktop>gcc main.obj -o main.exe

c:\Users\James\Desktop>main
Hello World!

(puts自动添加新行)