问题
Recently started learning Assembly so I'm relatively new to this. We use Linux back at school but I wanted to try coding on my PC. I'm using nasm on a Win8.1 64-bit system.
Here's the code:
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 seems to be running since it responds to the commands, but it doesn't execute the program:

How can I run the program? Is there something wrong with the code or is it system compatibilities? My last resort would be to install Ubuntu.
回答1:
I'll start with returning.
main.asm
[section] .text
global _main
_main:
mov eax, 6
ret ; returns eax (exits)
All this program does is return 6.
Assemble and link like so:
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
Using a stack frame.
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
compiling:
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
To use your own external functions you would:
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
compiling:
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
I'm pretty sure in your code instead of ret 16
, you mean int 80h
.
If so, you can't make system calls in windows
like you can in linux
,
but you can use gcc
to link with c's
library functions, for instance; stdio's puts
.
To use c
library functions like printf
or puts
you would do:
[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
And instead of using ld
(because the parameters are tough to get right),
you can just use gcc
on the obj
file like you would an ordinary c
source file.
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 adds a new line automatically)
来源:https://stackoverflow.com/questions/28733967/nasm-is-not-executing-file-in-windows-8