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?

Était-ce utile?

La 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
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top