nasm没有在Windows 8中执行文件

时间:2015-02-26 03:30:30

标签: windows assembly windows-8.1 nasm

最近开始学习大会,所以我对此比较陌生。我们在学校使用Linux,但我想尝试在我的电脑上编码。我在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似乎正在运行,因为它响应命令,但它没有执行程序:

command line in win8.1

我该如何运行该程序?代码有问题还是系统兼容性?我的最后一招是安装Ubuntu。

1 个答案:

答案 0 :(得分:1)

我开始回来。

<强> main.asm中

[section] .text
    global _main

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

所有这个程序都是返回6.

像这样组装和链接:

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

如果是这样,您无法像windows那样在linux进行系统调用, 但您可以使用gcc链接c's库函数,例如; stdio's puts

要使用cprintf这样的puts库函数,您可以这样做:

 [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(因为参数难以正确), 您可以像使用普通gcc源文件一样在obj文件上使用c

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会自动添加一个新行)