2015-02-26 3 views
0

Недавно началось обучение Ассамблее, поэтому я относительно новичок в этом. Мы используем Linux в школе, но я хочу попробовать кодирование на своем ПК. Я использую nasm в 64-разрядной системе Win8.1.nasm не выполняет файл в Windows 8

Вот код:

section .text 
    global [email protected] 

[email protected]: 
    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.

+3

Там что-то не так с кодом. Я не вижу никакого вызова в вашем 'asm', который будет печатать сообщение. Я просто вижу «ret 16» (возврат). – lurker

+0

Кроме того, nasm не имеет ничего общего с выполнением вашей программы. nasm участвует только в первом шаге, где ваш код сборки преобразуется в объектный код. – Michael

ответ

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.

Для использования c библиотечных функций, таких как printf или 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! 

(путы добавляет новую строку автоматически)

+0

Спасибо большое! – kshane