Ret Failure with SDL using FASM on Win32
I'm using SDL with FASM, and have code that's minimally like the following:
format ELF
extrn _SDL_Init
extrn _SDL_SetVideoMode
extrn _SDL_Quit
extrn _exit
SDL_INIT_VIDEO equ 0x00000020
section '.text'
public _SDL_main
_SDL_main:
ccall _SDL_Init, SDL_INIT_VIDEO
ccall _SDL_SetVideoMode, 640, 480, 32, 0
ccall _SDL_Quit
ccall _exit, 0 ; Success, or
ret ; failure.
With开发者_如何学JAVA the following quick-and-dirty makefile:
SOURCES = main.asm
OBJECTS = main.o
TARGET = SDLASM.exe
FASM = C:\fasm\fasm.exe
release : $(OBJECTS)
ld $(OBJECTS) -LC:/SDL/lib/ -lSDLmain -lSDL -LC:/MinGW/lib/ -lmingw32 -lcrtdll -o $(TARGET) --subsystem windows
cleanrelease :
del $(OBJECTS)
%.o : %.asm
$(FASM) $< $@
Using exit()
(or Windows' ExitProcess()
) seems to be the only way to get this program to exit cleanly, even though I feel like I should be able to use retn
/retf
. When I just ret
without calling exit()
, the application does not terminate and needs to be killed. Could anyone shed some light on this? It only happens when I make the call to SDL_SetVideoMode()
.
I noticed that ret
works to end the program, but as far as I know that's not guaranteed anywhere by Microsoft.
The official way to end a program is to call exit()
or ExitProcess()
.
(In C, the compiler has to arrange the code so that it is equivalent to calling exit()
.
Also, I suspect that a lot of existing programs use ret
instead, of it seems unlikely that Microsoft would change that behavior.)
About your problem, SDL does some black magic before your program is called: http://www.libsdl.org/faq.php?action=listentries&category=4#48.
I would suggest that you use a main()
entry point, as suggested in the FAQ.
to Bastien: the bit about ret and Microsoft doesn't make much sense, if you have a look at the source this is an ELF binary, which bears no relation to anything Microsoft-related.
of course a graceful exit is always the preferred way, so technically the exit() call is the right answer, but not because of the rationale you provide. (ie: because Microsoft say so)
on linux, DOS and other operating systems, an exit is just an interrupt call with certain parameters, which is normally used when don't want to link your programme with libc.
(for example, if you're writing something that runs in the kernel, or another operating system)
also, other compilers like freepascal (quite understandably) don't have dependency on the libc, the compiler just generates the appropriate interrupt call.
精彩评论