代码之家  ›  专栏  ›  技术社区  ›  Jon Purdy

在win32上使用fasm的sdl的ret失败

  •  1
  • Jon Purdy  · 技术社区  · 14 年前

    我将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.
    

    使用以下快速而脏的生成文件:

    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 不打电话 退出() ,应用程序不会终止,需要终止。有人能解释一下吗?只有当我打电话给 SDL_SetVideoMode() .

    2 回复  |  直到 14 年前
        1
  •  1
  •   Bastien Léonard    14 年前

    我注意到 ret 可以结束这个程序,但据我所知,微软在任何地方都不能保证这一点。 结束程序的官方方法是调用 exit() ExitProcess() .

    (在C语言中,编译器必须安排代码,使其与调用 退出() . 另外,我怀疑很多现有的程序使用 雷特 相反,微软似乎不太可能改变这种行为。)

    关于你的问题,SDL在你的程序被调用之前做了一些黑魔法: http://www.libsdl.org/faq.php?action=listentries&category=4#48 .
    我建议你用 main() 入口点,如常见问题解答中所建议的。

        2
  •  0
  •   vruz    14 年前

    对bastien来说:关于ret和微软的这一点没有多大意义,如果你看一下源代码,这是一个elf二进制文件,它与微软的任何相关内容都没有关系。

    当然,优雅的退出总是首选的方式,所以从技术上讲exit()调用是正确的答案,但不是因为您提供了理由。(因为微软这么说)

    在linux、dos和其他操作系统上,exit只是带有某些参数的中断调用,通常在不想将程序与libc链接时使用。

    (例如,如果您正在编写在内核或其他操作系统中运行的内容)

    另外,像freepascal这样的其他编译器(完全可以理解)并不依赖libc,编译器只是生成适当的中断调用。

    推荐文章