From: Ben Peddell User-Agent: Mozilla/5.0 (X11; U; Linux i586; en-US; rv:1.1) Gecko/20020826 X-Accept-Language: en-us, en MIME-Version: 1.0 Newsgroups: comp.os.msdos.djgpp Subject: Re: Bug 00314 -- div() still broken References: <3e9c6920$0$21928$afc38c87@> <3EA5477F DOT 2020901 AT cyberoptics DOT com> Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Lines: 89 Message-ID: Date: Fri, 25 Apr 2003 00:42:47 +1000 NNTP-Posting-Host: 144.139.175.101 X-Trace: newsfeeds.bigpond.com 1051194738 144.139.175.101 (Fri, 25 Apr 2003 00:32:18 EST) NNTP-Posting-Date: Fri, 25 Apr 2003 00:32:18 EST Organization: Telstra BigPond Internet Services (http://www.bigpond.com) To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Reply-To: djgpp AT delorie DOT com 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