On Apr 7, 3:54 pm, Cyril Novikov <spamt...@[EMAIL PROTECTED]
> wrote:
> junkoi wrote:
> > 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) are
> > doing the same thing, that is executing "func). But actually while (1)
> > works OK, (2) crashs. So confused!!
> [skip]
> > .code16gcc
>
> > call func // (1)
>
> > pushw $1f
> > jmp func // (2)
> > 1:
>
> > ....
> > func:
> > ret
>
> duh! In .code16gcc mode, all call's and ret's are treated by the
> assembler as 32-bit. This is to make sure function argument references
> off %ebp do the right thing. Remember that as far as GCC knows, it's
> producing 32 bit code. So, it will look for the first argument on stack
> at [%ebp+8], and there's nothing GNU assembler can do about it. Change
> pushw into pushl and that should do the trick.
Excellent, thanks! That solved my problem!!!
The reason I want to trick the stack because I think .code16gcc would
take 2 bytes from stack for "ret", but it turns out that it takes 4. I
am wrong here.
Now I want to fix my code, so it doesnt need to manipulate the stack
for that. My code below needs to call a function name func_32_16, in
which this function changes from 32bit to 16bit during its execution.
I expect that we just need to call func_32_16 normally. When we do
that, the return address (label "1" right after the call) will be
inserted into stack. Then when func_32_16 returns, it pops out this
address. And because .code16gcc takes 4 bytes out as normally, we
would jump to label "1". Things should work absolutely indifferently
from normal 32bit code.
However, my code crashs, so I guess the system doesnt work like I
suppose. Where am I wrong? How
Thanks,
Jun
.....
..code32
call func_32_16
1:
....
func_32_16:
..code32
// we are in 32bit mode at first
// then do something to switch from protected mode to real mode
// now we are in 16bit mode
..code16gcc
ret


|