Date: Sun, 30 Nov 1997 10:58:02 -0800 (PST) Message-Id: <199711301858.KAA28245@adit.ap.net> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" To: bobbymcn AT www DOT the-link DOT net, djgpp AT delorie DOT com From: Nate Eldredge Subject: Re: general protection fault Precedence: bulk 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