www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/11/30/14:00:57

Date: Sun, 30 Nov 1997 10:58:02 -0800 (PST)
Message-Id: <199711301858.KAA28245@adit.ap.net>
Mime-Version: 1.0
To: bobbymcn AT www DOT the-link DOT net, djgpp AT delorie DOT com
From: Nate Eldredge <eldredge AT ap DOT net>
Subject: Re: general protection fault

At 01:26  11/30/1997 -0600, Robert McNulty wrote:
>I have a problem. I get a "general protection fault at 160a".
>I can't fund the bug. I ried everything I could. here is the source
>code.
I see a few problems in this code.
>---------------snip---------------------------------

> asm ("
>  pushw %es
>
>  movw  _dos_seg, %es
>
>  movl  _string, %esi
>  movl  $0xb8000, %edi
>
>  movw  _length, %cx
This needs to be `movl _length, %ecx'.
>
>  rep ; movsb
>
>  popw  %es
> ");
You have to tell the compiler what registers you have clobbered. In this
case, %esi, %edi, and %ecx. See `info gcc "C Extensions" "Extended Asm"' for
more info.
>
>SetMode13();
>SlowPutPxl(x, y, color);
>}
>
>
>
> void SetMode13()
>
> {
>
> dos_seg = _go32_conventional_mem_selector();
>
>asm("
>  pushw %es
>
>  movw  _dos_seg, %es
>
>
>     mov $0x002, %ax
Should be `movw'
>     movw $0xA0000, %bx
You are loading 0xA0000, which is larger than 65535, into a 16-bit register.
Think about what you really want here.
>     int $0x02f
>     xor  %ah, %ah
>     mov   $0x013, %al
>     int  $0x010
>
>
>    movw  $0x0A0000, %edi
>    movw %di ,%es
Here you load %edi with 0xa0000, which means the low half (%di) of %edi
contains 0. Then you load it into %es, which means %es now contains the null
selector. Since you don't put something sensible in it before going back
into GCC-compiled code, the next time the compiler tries to use %es, it will
crash.
>    xor  %di, %di
>           ret
Here you return without fixing the stack frame. You should let the compiler
handle the returns for you.
>");
Again, say what registers are clobbered.
>}

>void SetText()
>{    asm("        movl  $0x003, %ax
>                  int $0x10
>                  ret
>                  ");
>}
>
>void SlowPutPxl(int x, int y, int color)
>{
>   dos_seg = _go32_conventional_mem_selector();
>asm("
>               pushw %es
>
>                 movw  _dos_seg, %es
>
>                  push %ebp
>                  movl %sp, %bp
First, you don't need to set up a stack frame (the compiler handles that),
and second, you're doing it wrong.
>                  pushw %es
>                  pushw %di
>
>                  movw $0xA0000, %ax
Again, moving too large of a value into a 16-bit register.
>                  movw %ax, %es
>                  movw %bp+8, %ax
Are you trying to access your parameters here? This is not a good way to go
about it, and there are several problems with the way you do it. GCC's
inline asm features provide a much better way; see the reference above.
>                  movw  320, %cx
>                  mul %cx
>                   add %bp+6, %ax
>                    movw  %ax, %di
>
>                  movw  %bp+10, %di
>                  movw  %di, %di
>                  popw %di
>                  popw %es
>
>                  movw %bp, %sp
>                  popw %bp
>                  ret
Again, don't do this.
>");
>}
I think going through this with a debugger might be very helpful. edebug32
and fsdb both work well for debugging assembly. GDB can also, but it's
slightly more complicated (I think `display/i %pc' gives you a running
disassembly and `si' steps one instruction).


Nate Eldredge
eldredge AT ap DOT net



- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019