Question

I am trying to write a simple snake-like game in 32bit x86 AT&T assembly, and I've come a cross a strange problem. I have a few C-functions which I use for some tasks, such as printing to the screen using ncurses. This particular function, snake_print, looks like this:

snake_print(int x, int y, int ch){
    mvprintw(y,x,"%c",ch);
    wrefresh(screen);
}

where put_char put's the character ch on the screen and refresh_scr refreshes it. The variable screen is global.

So, to call this I put some values on the stack, like this:

subl  $12,%esp
pushl $'o'
pushl $15
pushl $15
call snake_print
addl  $12,%esp

When I look at the stack with GDB from the snake_print function, it looks as it should. It moves down to where it is supposed to return from the functions with correct stack content, and then something happens; when GDB makrks } in snake_print as being the code running, the value 0x804d190 is put on the stack, along with a call to snake_print(0x804d190,15,111). The next line of code executed is, again, refresh_scr(scr) and then I get a segmentation fault.

I examined 0x804d190 with GDB and saw that it contained the value 0x10000f. Since, in the new call to snake_print, my previous x-value of 15 is exchanged for 0x804d190, it would seem that something has happened to the memory address where the x-value was stored, since 15 = 0xf and we're "just one off", so to speak.

I have no idea whatsoever why this happens, so I was wondering if anyone could help figure out what is wrong?

Was it helpful?

Solution

You're mixing two approaches of passing the arguments. Because both subl and the pushes change the stack, the addl is not enough to re-balance it and so your program crashes later.

You should use one or the other:

1) using pushes and restoring the stack after calls.

pushl $'o'
pushl $15
pushl $15
call snake_print
addl  $12,%esp
<...>
pushl $'p'
pushl $12
pushl $12
call snake_print
addl  $12,%esp

2) allocating stack once and using movs to set arguments.

subl  $12,%esp
<...>
movl $'o', 8(%esp)
movl $15, 4(%esp)
movl $15, 0(%esp)
call snake_print
<...>
movl $'p', 8(%esp)
movl $12, 4(%esp)
movl $12, 0(%esp)
call snake_print
<...>
addl  $12,%esp
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top