views:

137

answers:

2

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 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().

+1  A: 

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&amp;category=4#48.
I would suggest that you use a main() entry point, as suggested in the FAQ.

Bastien Léonard
Alright, `exit()` it is. I used `SDL_main()` instead of `main()` because `SDL_main.h` includes the infamous line `#define main SDL_main` for Windows and Mac. I'll experiment a bit.
Jon Purdy
A: 

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.

vruz