Calling SDL from assembly on Windows

I’m trying to call SDL functions from assembly code, and assemble it
with NASM and link it using MinGW under Windows. I’ve gotten it to
assemble and link just fine, but when I run the program it crashes. I
think I’m just missing something. Here’s the assembly code:

--------------------------sdl_test.asm-------------------------------

BITS 32

GLOBAL _main

EXTERN _SDL_Init
EXTERN _SDL_Quit
EXTERN _SDL_SetVideoMode

SDL_INIT_VIDEO EQU 00000020h

 SECTION    .text

_main

 push    dword SDL_INIT_VIDEO
 call    _SDL_Init
 add    esp, 4

 push    dword 0
 push    dword 32
 push    dword 480
 push    dword 640
 call    _SDL_SetVideoMode
 add    esp, 16

 call    _SDL_Quit

 ret

--------------------------sdl_test.asm-------------------------------

and the Makefile:

----------------------------Makefile---------------------------------

PROGNAME=sdl_test

all: $(PROGNAME).exe

clean:
-rm $(PROGNAME).exe

remake: clean all

%.exe: %.o
D:\MinGW\bin\gcc -o sdl_test sdl_test.o -lmingw32 libSDLmain.a
libSDL.a -mwindows

%.o: %.asm
nasm -f coff -o$ $.o $< -l $.lst

----------------------------Makefile---------------------------------

I’m using the MinGW devel version of the SDL libraries to link against.
In case it helps, the crash seems to occur during the call to SDL_Init.

Thanks,
Shawn Lindberg

I assume you’ve had the C equivilant compile and work
fine? I’m guessing it has to do something with hidden
compiler magic or initialization… have you tried
naming your entry _SDL_main? I think you might have to
do that on windows? (I cant check my old code as I’m
at school atm…)

— Shawn Lindberg wrote:

I’m trying to call SDL functions from assembly code,
and assemble it
with NASM and link it using MinGW under Windows.
I’ve gotten it to
assemble and link just fine, but when I run the
program it crashes. I
think I’m just missing something. Here’s the
assembly code:

--------------------------sdl_test.asm-------------------------------

BITS 32

GLOBAL _main

EXTERN _SDL_Init
EXTERN _SDL_Quit
EXTERN _SDL_SetVideoMode

SDL_INIT_VIDEO EQU 00000020h

 SECTION    .text

_main

 push    dword SDL_INIT_VIDEO
 call    _SDL_Init
 add    esp, 4

 push    dword 0
 push    dword 32
 push    dword 480
 push    dword 640
 call    _SDL_SetVideoMode
 add    esp, 16

 call    _SDL_Quit

 ret

--------------------------sdl_test.asm-------------------------------

and the Makefile:

----------------------------Makefile---------------------------------

PROGNAME=sdl_test

all: $(PROGNAME).exe

clean:
-rm $(PROGNAME).exe

remake: clean all

%.exe: %.o
D:\MinGW\bin\gcc -o sdl_test sdl_test.o
-lmingw32 libSDLmain.a
libSDL.a -mwindows

%.o: %.asm
nasm -f coff -o$ $.o $< -l $.lst

----------------------------Makefile--------------------------------->

I’m using the MinGW devel version of the SDL
libraries to link against.
In case it helps, the crash seems to occur during
the call to SDL_Init.

Thanks,
Shawn Lindberg


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


Do you Yahoo!?
Yahoo! Small Business $15K Web Design Giveaway
http://promotions.yahoo.com/design_giveaway/

Shawn Lindberg wrote:

I’m trying to call SDL functions from assembly code, and assemble it
with NASM and link it using MinGW under Windows. I’ve gotten it to
assemble and link just fine, but when I run the program it crashes. I
think I’m just missing something. Here’s the assembly code:

[code]

I’m using the MinGW devel version of the SDL libraries to link
against. In case it helps, the crash seems to occur during the call
to SDL_Init.

It works under linux after some small modifications :
http://icps.u-strasbg.fr/~marchesin/sdl/sdl_asm.tgz
(maybe that’ll help you)

Under windows, you’ll have to use a SDL_main function instead of a main
function.

Stephane

Compile it in C, and look at the assembly with “objdump -S”; see what
you’re doing differently.

That aside, why are you doing this? I can’t think of any interesting
reason to want to make SDL calls from assembly; at application level
these days, assembly is for time-critical inner loops, and time-critical
inner loops don’t generally make SDL calls.On Wed, Apr 07, 2004 at 03:44:33PM -0500, Shawn Lindberg wrote:

I’m trying to call SDL functions from assembly code, and assemble it
with NASM and link it using MinGW under Windows. I’ve gotten it to
assemble and link just fine, but when I run the program it crashes. I
think I’m just missing something. Here’s the assembly code:


Glenn Maynard

That aside, why are you doing this? I can’t think
of any interesting reason to want to make SDL calls
from assembly;

I can: script compiler producing pre-assembeled code
that makes SDL calls.

^^_________________________________
Do you Yahoo!?
Yahoo! Small Business $15K Web Design Giveaway
http://promotions.yahoo.com/design_giveaway/

Stephane Marchesin wrote:

It works under linux after some small modifications :
http://icps.u-strasbg.fr/~marchesin/sdl/sdl_asm.tgz
(maybe that’ll help you)

Yes, unfortunately, it’s much simpler on Linux, which is why I’ve
focused on getting it to work in Windows first.

Under windows, you’ll have to use a SDL_main function instead of a main
function.

Both you and Michael Rickert suggested this, so I tried it. At first,
when I tried it, it worked, and I thought I had it beat. However, I was
suspicious, so I added this code:

.loop
call _SDL_PumpEvents

push	dword 0
call	_SDL_GetKeyState
add	esp, 4

cmp	byte [ eax + SDLK_q ], 0
je	.loop

I put this right after the call to SetVideoMode. And guess what, it
crashes again… I really don’t get it.

Shawn Lindberg

Glenn Maynard wrote:

I’m trying to call SDL functions from assembly code, and assemble it
with NASM and link it using MinGW under Windows. I’ve gotten it to
assemble and link just fine, but when I run the program it crashes. I
think I’m just missing something. Here’s the assembly code:

Compile it in C, and look at the assembly with “objdump -S”; see what
you’re doing differently.

I don’t have time to try this at the moment, but thanks for the suggestion.

That aside, why are you doing this? I can’t think of any interesting
reason to want to make SDL calls from assembly; at application level
these days, assembly is for time-critical inner loops, and time-critical
inner loops don’t generally make SDL calls.

It’s for a class. The class is on x86 assembly, and it’s got all these
Windows specific library functions to use. I thought I could make it
better by using SDL to make the library functions more portable.

Shawn Lindberg> On Wed, Apr 07, 2004 at 03:44:33PM -0500, Shawn Lindberg wrote:

Well the doc project is down at the moment, but I
thought SDL_GetKeyState takes an argument that is a
pointer to the array to be filled?

push dword 0
call _SDL_GetKeyState

Would seem to me that you’re passing a null pointer,
thus causing the program to segfault when it tries to
fill said array?

— Shawn Lindberg wrote:> Stephane Marchesin wrote:

It works under linux after some small
modifications :

http://icps.u-strasbg.fr/~marchesin/sdl/sdl_asm.tgz

(maybe that’ll help you)

Yes, unfortunately, it’s much simpler on Linux,
which is why I’ve
focused on getting it to work in Windows first.

Under windows, you’ll have to use a SDL_main
function instead of a main
function.

Both you and Michael Rickert suggested this, so I
tried it. At first,
when I tried it, it worked, and I thought I had it
beat. However, I was
suspicious, so I added this code:

.loop
call _SDL_PumpEvents

push dword 0
call _SDL_GetKeyState
add esp, 4

cmp byte [ eax + SDLK_q ], 0
je .loop

I put this right after the call to SetVideoMode.
And guess what, it
crashes again… I really don’t get it.

Shawn Lindberg


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


Do you Yahoo!?
Yahoo! Small Business $15K Web Design Giveaway
http://promotions.yahoo.com/design_giveaway/

not sure what the parameter to sdl_getkeystate is, but it returns a pointer
to the state of the keys, it doesnt fill an array or anything.

unsigned char *Keys;
Keys=SDL_GetKeyState(0);

that code works fine so dont think thats the problem.> ----- Original Message -----

From: mrickert85@yahoo.com (Michael Rickert)
To:
Sent: Thursday, April 08, 2004 11:51 AM
Subject: Re: [SDL] Calling SDL from assembly on Windows

Well the doc project is down at the moment, but I
thought SDL_GetKeyState takes an argument that is a
pointer to the array to be filled?

push dword 0
call _SDL_GetKeyState

Would seem to me that you’re passing a null pointer,
thus causing the program to segfault when it tries to
fill said array?

— Shawn Lindberg wrote:

Stephane Marchesin wrote:

It works under linux after some small
modifications :

http://icps.u-strasbg.fr/~marchesin/sdl/sdl_asm.tgz

(maybe that’ll help you)

Yes, unfortunately, it’s much simpler on Linux,
which is why I’ve
focused on getting it to work in Windows first.

Under windows, you’ll have to use a SDL_main
function instead of a main
function.

Both you and Michael Rickert suggested this, so I
tried it. At first,
when I tried it, it worked, and I thought I had it
beat. However, I was
suspicious, so I added this code:

.loop
call _SDL_PumpEvents

push dword 0
call _SDL_GetKeyState
add esp, 4

cmp byte [ eax + SDLK_q ], 0
je .loop

I put this right after the call to SetVideoMode.
And guess what, it
crashes again… I really don’t get it.

Shawn Lindberg


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl


Do you Yahoo!?
Yahoo! Small Business $15K Web Design Giveaway
http://promotions.yahoo.com/design_giveaway/


SDL mailing list
SDL at libsdl.org
http://www.libsdl.org/mailman/listinfo/sdl

Alan Wolfe wrote:

not sure what the parameter to sdl_getkeystate is, but it returns a pointer
to the state of the keys, it doesnt fill an array or anything.

unsigned char *Keys;
Keys=SDL_GetKeyState(0);

that code works fine so dont think thats the problem.

Right, the parameter is the number of keys - but I don’t know what that
means. Anyway, the code with 0 is in the doc project.

Shawn Lindberg

Red herring on my part. FYI, the parameter to
SDL_GetKeyState is a pointer to an int which will be
set to the number of keys the array has.
(http://sdldoc.csn.ul.ie/sdlgetkeystate.php, now that
the doc project is up again)

I’m not seeing anything else… you said you were
trying this on windows, right? I’ll try compiling the
same on linux, thus seeing if the problem is OS
specific or if we’re doing something wrong that’s
multi-platform…

As an aside, prehaps passing SDL_EVENT_THREAD to init
might help? Placing the event handling code into a
seperate thread might make SDL init something that
isn’t getting init. on our code??? I’ll also try an
assembly dump of C version code…

ATM @ School, so I’ll check when I get home.> Alan Wolfe wrote:

not sure what the parameter to sdl_getkeystate is,
but it returns a pointer
to the state of the keys, it doesnt fill an array
or anything.

unsigned char *Keys;
Keys=SDL_GetKeyState(0);

that code works fine so dont think thats the
problem.

Right, the parameter is the number of keys - but I
don’t know what that
means. Anyway, the code with 0 is in the doc
project.

Shawn Lindberg


Do you Yahoo!?
Yahoo! Small Business $15K Web Design Giveaway
http://promotions.yahoo.com/design_giveaway/

Michael Rickert wrote:

isn’t getting init. on our code??? I’ll also try an
assembly dump of C version code…

I finally figured it out. I did an assembly dump of my assembly and
compared it to the dump from a C version. The calls were being
mistranslated, for whatever reason. So I tried changing nasm’s output
format. I found one that worked - win32. Seems kind of obvious, now,
right?

Anyway, just in case anyone ever wants to follow my work, here’s a demo
source and its Makefile. Supposedly you could get the code to compile
on Linux if you pass -fno-leading-underscore to gcc, but I tried it and
it didn’t work. Wouldn’t mind knowing what’s up with that… Oh, and
just in case anyone cares, either djgpp or mingw versions of gcc worked
for me.

-----------------------sdl_test.asm---------------------------

BITS 32

GLOBAL _SDL_main

EXTERN _SDL_Init
EXTERN _SDL_Quit
EXTERN _SDL_SetVideoMode
EXTERN _SDL_PumpEvents
EXTERN _SDL_GetKeyState

SDL_INIT_VIDEO EQU 00000020h
SDLK_q EQU 113

SECTION .text

_SDL_main

push	dword SDL_INIT_VIDEO
call	_SDL_Init
add	esp, 4

push	dword 0
push	dword 32
push	dword 480
push	dword 640
call	_SDL_SetVideoMode
add	esp, 16

.loop
call _SDL_PumpEvents

push	dword 0
call	_SDL_GetKeyState
add	esp, 4

cmp	byte [ eax + SDLK_q ], 0
je	.loop

call	_SDL_Quit

ret

-----------------------sdl_test.asm---------------------------

-------------------------Makefile-----------------------------

PROGNAME=sdl_test

all: $(PROGNAME).exe

clean:
-rm $(PROGNAME).exe

remake: clean all

%.exe: %.o
gcc -o sdl_test sdl_test.o -lmingw32 libSDLmain.a libSDL.a

%.o: %.asm
nasm -f win32 -o$ $.o $< -l $.lst

-------------------------Makefile-----------------------------

Michael Rickert wrote:

Red herring on my part. FYI, the parameter to
SDL_GetKeyState is a pointer to an int which will be
set to the number of keys the array has.
(http://sdldoc.csn.ul.ie/sdlgetkeystate.php, now that
the doc project is up again)

I’m not seeing anything else… you said you were
trying this on windows, right? I’ll try compiling the
same on linux, thus seeing if the problem is OS
specific or if we’re doing something wrong that’s
multi-platform…

As an aside, prehaps passing SDL_EVENT_THREAD to init
might help? Placing the event handling code into a
seperate thread might make SDL init something that
isn’t getting init. on our code??? I’ll also try an
assembly dump of C version code…

I tried this under linux the other day, and it works. And the code seems
correct to me, so this is probably some windows-specific problem.

Stephane

Michael Rickert wrote:

I’m not seeing anything else… you said you were
trying this on windows, right? I’ll try compiling the
same on linux, thus seeing if the problem is OS
specific or if we’re doing something wrong that’s
multi-platform…

Well, I know that similar assembly will link on Linux, and run just
fine. The trick for me has been trying to get it working in Windows.
Eventually I’m hoping to get one source file that can be linked on both,
but I had reason to believe that Windows’d be the harder gig, and so
far, it looks like that’s right ;).

As an aside, prehaps passing SDL_EVENT_THREAD to init
might help? Placing the event handling code into a
seperate thread might make SDL init something that
isn’t getting init. on our code??? I’ll also try an
assembly dump of C version code…

I’ll try that and the C approach tomorrow. Maybe between the two of us
we can figure this out =).

Shawn