beyondsociety wrote:
When I enable interrupts, I get a divisor by 0 exception error.
How would I check if there is a divisor by 0 or not?
Well, first off, I would be suspect of the exception arising at all. Division simply isn't a common operation in system code, and if it is coming up that quickly and regularly, I would definitely wonder why it would be happening. What is telling you that it is a divide-by-zero error - your interrupt handler, or the simulator you're running it in (Bochs, Plex86, VMware, etc)? Are you sure that you have the PIC reprogrammed correctly, that the IDT has the correct interrupt vectors, etc.?
In any case, it is still a good idea to check for possible division-by-zero error any time you have a variable divisor, in order to avoid that error. you need to determine each instance in your OS code where you are performing a divison. If the divisor is a constant, then there shouldn't be a problem; but if the divisor is a variable, then you'll want to add a check to make sure it isn't zero. Thus instead of
Code: Select all
foo = bar / (baz - quux); // will cause DivZ error if baz == quux
you would use an intermediate value to test the divisor, and add a follow-up to handle the problem cases:
Code: Select all
xoom = baz - quux; // intermediate value holding the the divisor of the next expression
if (xoom != 0)
foo = bar / xoom;
else
{
// do whatever you need to do instead of the division
}
This is actually easier in x86 assembly, as you can usually take advantage of the order of operations, so that for
Code: Select all
mov ebx, [baz] ; move baz into ebx register
sub ebx, [quux] ; and subtract quux by it
mov eax, [bar] ; move bar into eax register
div ebx ; and divide it by the result of baz - quux
mov [foo], eax ; save result in foo
; ...
you would only need to add a jump-on-zero after the subtraction:
Code: Select all
mov ebx, [baz] ; move baz into ebx register
sub ebx, [quux] ; and subtract quux by it
; because a subtraction resulting in zero sets the clear flag
; there is no need for the intermediate value 'xoom'
jz handle_zero_case ; if the result is zero, don't do the divsion
mov eax, [bar] ; move bar into eax register
div ebx ; and divide it by the result of baz - quux
mov [foo], eax ; save result in foo
handle_zero_case:
; ...
HTH.