Сбой Ret с SDL с использованием FASM на Win32 - PullRequest
1 голос
/ 31 марта 2010

Я использую SDL с FASM, и у меня есть код, который минимально похож на следующий:

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.

Со следующим быстрым и грязным make-файлом:

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) $< $@

Использование exit() (или Windows ExitProcess()), кажется, единственный способ заставить эту программу корректно завершиться, хотя я чувствую, что должен иметь возможность использовать retn / retf. Когда я просто ret без вызова exit(), приложение не завершается и должно быть убито. Может ли кто-нибудь пролить свет на это? Это происходит только тогда, когда я звоню SDL_SetVideoMode().

Ответы [ 2 ]

1 голос
/ 01 апреля 2010

Я заметил, что ret работает, чтобы завершить программу, но, насколько я знаю, это нигде не гарантировано Microsoft. Официальный способ завершить программу - позвонить exit() или ExitProcess().

(В C компилятор должен расположить код так, чтобы он был эквивалентен вызову exit(). Кроме того, я подозреваю, что многие существующие программы используют вместо этого ret, хотя вряд ли Microsoft изменит это поведение.)

Что касается вашей проблемы, SDL совершает некоторую чёрную магию перед вызовом вашей программы: http://www.libsdl.org/faq.php?action=listentries&category=4#48.
Я бы посоветовал вам использовать main() точку входа, как это предлагается в FAQ.

0 голосов
/ 12 мая 2010

Бастиену: немного о ret и Microsoft не имеет особого смысла, если вы посмотрите на источник, это бинарный файл ELF, который не имеет никакого отношения к чему-либо связанному с Microsoft.

Конечно, изящный выход всегда является предпочтительным способом, поэтому технически вызов exit () является правильным ответом, но не из-за предоставленного вами обоснования. (то есть: потому что Microsoft так говорит)

в Linux, DOS и других операционных системах, выход - это просто вызов прерывания с определенными параметрами, который обычно используется, когда вы не хотите связывать вашу программу с libc.

(например, если вы пишете что-то, что работает в ядре или другой операционной системе)

также, другие компиляторы, такие как freepascal (вполне понятно), не зависят от libc, компилятор просто генерирует соответствующий вызов прерывания.

...