Page 1 of 1

ASM: manipulate stack for calling in 16bit mode (.code16gcc)

Posted: Sun Apr 06, 2008 10:54 pm
by junkoi
Hi,

I am writing some code in 16bit mode, using .code16gcc directive, and compile with gcc 4.1. In the below code, I expect that (1) and (2) do the same thing, that is executing "func). But actually while (1) works OK, (2) crashs. So confused!!

Perhaps because "pushw" pushs 4 bytes into stack instead of 2 bytes with .code16gcc??? (sorry I only guess after reading the Intel manual, but cannot verify it!)

Many thanks,
Jun

------
.code16gcc

call func // (1)

pushw $1f
jmp func // (2)
1:

....
func:
ret

Posted: Mon Apr 07, 2008 1:49 am
by AJ
Hi,

I would suggest doing a disassembly and making sure you really are pushing the correct return value in (2). I'm not familiar enough with at&t to say whether $1f really does point to your label '1:', though. Why not just use call, anyway?

Cheers,
Adam

Posted: Mon Apr 07, 2008 3:08 am
by JamesM
I'm not familiar enough with at&t to say whether $1f really does point to your label '1:', though.
It does. Numeric labels are handled differently - $1f means "the next 1:, searching forward from this location". There's a $1b as well ;)

Posted: Mon Apr 07, 2008 4:20 am
by AJ
Well, you learn something every day :)

Posted: Mon Apr 07, 2008 7:14 am
by devel
I didn't try but maybe this works

Code: Select all

.code16gcc

call func // (1)

pushl $1f
jmp func // (2)
1:

....
func:
retl

Posted: Mon Apr 07, 2008 8:03 am
by junkoi
devel wrote:I didn't try but maybe this works

Code: Select all

.code16gcc

call func // (1)

pushl $1f
jmp func // (2)
1:

....
func:
retl
Yes, this works! The reason is that .code16gcc treats "ret" like normal 32bit code, that is it pops 32bit address from stack rather than 16bit. So "pushl $1f" is the key here!

Thanks so much,
J