cant seem to get my head around this problem, im sure its something that im missing...
it *seems* that for a particular "for" loop in my C code, the compiler (GNU 4.5.2) has produced an endless loop.
the "for" loop should only loop 200 or so times, but when i step through the code in the debugger while running it on Bochs, the op-code that is being run *correctly* sets ebx to the counting variable's ("i" in the C code) initial value and *correctly* increments ebx on each loop iteration as i step through the running code, *BUT* there is no comparison of ebx to my "upper limit" at which the loop is supposed to cease - in the decompiled assembly there is only an unconditional "jmp .-25" and hence i get an endless loop...
anyway, i need to give some solid information so here it is:
C compiler: GNU 4.5.2
Bochs: my *debugging* version is custom-compiled with just about all features (SMP, APIC, USB etc) (yes i know its slow, but i have a "lean" version for fast non-debugging tests )
here is a snippet of the C-Source code around the offending "for" loop (p.s. IDT_ENTRIES == 256):
Code: Select all
//...
idt_SetGate(IRQ_Map[14], IRQ14, ring0_Code, IDT_FLAGS_RING0);
idt_SetGate(IRQ_Map[15], IRQ15, ring0_Code, IDT_FLAGS_RING0); /** eip = 0x0000be47 **/
// finished remapping PIC IRQs
// (for now)... just register the rest of the interrupts up to 255 to run ISR048
for(i = 48; i <= (IDT_ENTRIES - 1); i++) {
idt_SetGate(i, ISR048, ring0_Code, IDT_FLAGS_RING0);
}
// register the kernel data descriptor to use for interrupt routines
// (write to _ISR_kernel_data_descriptor, located in ISR.asm)
ISR_kernel_data_descriptor = ring0_Data;
// initialise all external interrupt drivers to NULL
struct InterruptHandler_s null_Handler;
null_Handler.handlerFunction = 0;
for(i = 0; i <= (IDT_ENTRIES - 1); i++) {
idt_RegisterInterruptHandler(i, null_Handler);
}
// set the new IDT
idt_Flush();
}
and the corresponding dissassembled code... (im pretty sure this is it, but maybe ive not followed my debug-stepping closely enough due to lack of sleep... eitherway im going to be rechecking over it so ill update if what i post here turns out to be wrong)
Code: Select all
L.Address (bytes) Opcode Mnemonic
---------------------------------------------------------
0x0000be47 (5) e858faffff call .-1448 (0x0000b8a4) <see corresponding C-code comment>
0x0000be4c (2) b330 mov bl, 0x30
0x...be4e (3) 0fb6c3 movzx eax, bl
be51 (7) c704248e000000 mov dword ptr ss:[esp], 0x0000008e
be58 (2) 89f1 mov ecx, esi
be5a (5) ba7fb40000 mov edx, 0x0000b47f
be5f (5) e840faffff call .-1472 (0x0000b8a4)
be64 (1) 43 inc ebx
be65 (2) ebe7 jmp .-25 (0x0000be4e)
be67 (1) 90 nop
be68 (5) 0fb6442404 movzx eax, byte ptr ss:[esp+4]
be6d (4) 8b542408 mov edx, dword ptr ss:[esp+8]
be71 (7) 89148514f00000 mov dword ptr ds:[eax*4+61460], edx
be78 (1) c3 ret
be79 (1) c3 ret
be7a (1) 57 push edi
be7b (1) 56 push esi
be7c (3) ... ...
--------------------------------------------------------------------------------
at eip = 0x0000be4c (just after the last function call returns, right before entering the offending "for" loop) the registers are:
eax = 0x0000008e
ebx = 0x0000000a
ecx = 0x0000e2b8
edx = 0x00000008
esi = 0x00000008
edi = 0x00007ac0
ebp = 0x00000000
esp = 0x000079a0
(segment registers are all correct GDT entries, etc)
thanks!!