Mail Archives: djgpp/1997/11/30/14:00:57
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 -