Mail Archives: djgpp/2003/04/24/10:45:24
Eric Rudd wrote:
> Ben Peddell wrote:
>
>> From your crash, it looks like the divide was being called something
>> like:
>> result = div(-3,-3);
>
>
> Those args shouldn't even cause it to bomb. I think I had some problem
> with -fomit-frame-pointer, but I'm still investigating.
>
I was simply saying by the fact that your register dump had:
> eax=fffffffd ebx=fffffffd ecx=00000000 edx=ffffffff
Which implies that it could have been dividing 0xFFFFFFFFFFFFFFFD by
0xFFFFFFFD.
True,
{
int x, y, z;
z = x / y;
return z;
}
Does not bomb, and I confirmed that it uses a idivl.
I was wrong in div(-3,-3). The -3 in ebx was from gcc putting numerator
in it before putting it in eax.
Things are being pushed wrong.
edi is supposed to hold the address of the div_t structure, yet is has
0x28 (40) in it. eax and ebx are supposed to have 40 in them, yet they
have -3 in them.
div() wants the stack to look like:
16(%ebp): divisor
12(%ebp): numerator
8(%ebp): &return
But it appears to look like:
16(%ebp): something between -2 and +2
12(%ebp): divisor
8(%ebp): numerator
There in lies the problem.
Here is the disassembly from div.o in libc.a:
div:
pushl %ebp
movl %esp, %ebp
subl $8, %esp
pushl %edi
pushl %esi
pushl %ebx
movl 8(%ebp), %edi
movl 12(%ebp), %ebx
testl %ebx, %ebx
jle L1
cmpl $0, 16(%ebp)
jge L1
negl %ebx
negl 16(%ebp)
L1:
movl %ebx, %eax
cdq
idivl 16(%ebp)
movl %eax, -8(%ebp)
movl %edx, %esi
movl %esi, -4(%ebp)
testl %ebx, %ebx
jle L2
cmpl $0, 16(%ebp)
jg L2
testl %esi, %esi
jg L2
incl -8(%ebp)
movl 16(%ebp), %eax
subl -4(%ebp), %eax
L2:
movl -8(%ebp), %edx
movl %edx, (%edi)
movl -4(%ebp), %edx
movl %edx, 4(%edi)
movl %edi, %eax
leal -4(%ebp), %esp
popl %ebx
popl %esi
popl %edi
leave
ret
- Raw text -