From: Gertjan Klein Newsgroups: comp.os.msdos.djgpp Subject: Re: error idiv :divide by zero Date: 27 Dec 1997 13:19:59 +0100 Organization: XS4ALL, networking for the masses Message-ID: <682rpf$66d$1@xs2.xs4all.nl> References: <34A430E1 DOT 2495 AT bluewin DOT ch> NNTP-Posting-Host: xs2.xs4all.nl Lines: 68 To: djgpp AT delorie DOT com DJ-Gateway: from newsgroup comp.os.msdos.djgpp Precedence: bulk In article <34A430E1 DOT 2495 AT bluewin DOT ch>, leger_v AT bluewin DOT ch wrote: > static unsigned char quotient; > static unsigned char remainder; > main() > { asm("pusha > movb $8,%al ;2 samples numbers > movb $3,%cl ; > idiv %cl > mov %al, _quotient > mov %ah, _remainder > popa"); > printf("8 : 3 = %d and remainder : %d" quotient, remainder); >} > this program works fine. No it doesn't; it doesn't even compile. There is a comma missing after the printf format specifier, and the assembler chokes on the colon comments (use /* C comments */ instead). Always cut-and-paste from the actual code you tried, to prevent people on the list from chasing typing errors instead of finding the real problem. > But if I use word register like %ax > (movw $998, %ax)and %cx(movw $98, %cx)(naturally quotient and remainder > are unsigned int)the program doesn't function : it writes: "error divide > by zero). How could I use bigger registers (word or dword) without > having "divide by zero"? The "divide by zero" is not a very accurate error message; it should read "divide overflow". Actually, the (byte size) code you posted only works by accident, too (i.e., it could have given the same error message). Try adding "movb $4,%ah% after the pusha above to see that happen (note that %ah can contain anything, since you don't set it yourself). In the 80x86 instuction set, "idiv %cl" divides %ax (not %al) by %cl; similarly, "idiv %cx" divides %dx:%ax by %cx. So, if you want to divide a (16-bit) word by another (16-bit) word, just zero-out %dx first. Another problem in your code is that you do a signed division on unsigned integers; either change the "idiv" to "div", or remove the "unsigned" from the variable declarations. So, to do a (16-bit) word division: #include static unsigned short quotient; static unsigned short remainder; int main(void) { asm("pusha movw $0,%dx /* Zero-out high part of dword */ movw $998,%ax movw $98,%cx div %cx mov %ax, _quotient mov %dx, _remainder popa"); printf("998 : 98 = %d and remainder : %d", quotient, remainder); return 0; } Hope this helps, Gertjan. -- Gertjan Klein The Boot Control home page: http://www.xs4all.nl/~gklein/bcpage.html */ __dpmi_int (0x2F, &dpmi_regs); /* Free the memory */ __dpmi_free_dos_memory(alloc_desc); /* Return result */ if (dpmi_regs.x.ax != 0) return(0); /* Fail by default */ return(-1); } /* ------------------- - w95_getapptitle - ------------------- */ int w95_getapptitle (char *apptitle, int maxlen) { __dpmi_regs dpmi_regs; /* Registers for function call */ int alloc_seg; /* Allocated memory's segment */ int alloc_desc; /* Allocated memory's descriptor */ /* Allocate some DOS memory */ alloc_seg = __dpmi_allocate_dos_memory(APP_TITLE_BUFFER_PARA, &alloc_desc); if (alloc_seg == -1) return(-1); /* Put the title in it */ //movedata(_my_ds(), (int) apptitle, alloc_desc, 0, strlen(apptitle) + 1); /* Set up the registers - nuke DX as part of this; set AX to set the app title */ memset (&dpmi_regs, 0, sizeof(dpmi_regs)); dpmi_regs.x.ax = 0x168E; dpmi_regs.x.dx = 0x0002; /* Get title */ dpmi_regs.x.cx = APP_TITLE_BUFFER_LEN; /* Buffer size */ dpmi_regs.x.es = alloc_seg; /* Segment */ dpmi_regs.x.di = 0; /* Offset */ /* Interrupt */ __dpmi_int (0x2F, &dpmi_regs); /* Copy the string into apptitle - truncate it if there's not enough space */ if (maxlen > APP_TITLE_BUFFER_LEN) maxlen = APP_TITLE_BUFFER_LEN; movedata(alloc_desc, 0, _my_ds(), (int) apptitle, maxlen); apptitle[maxlen] = 0; /* Free the memory */ __dpmi_free_dos_memory(alloc_desc); /* Return result */ if (dpmi_regs.x.ax != 0) return(0); /* Fail by default */ return(-1); } /* -------------------- - w95_setvmmtitle - -------------------- */ int w95_setvmmtitle (char *vmmtitle) { __dpmi_regs dpmi_regs; /* Registers for function call */ int alloc_seg; /* Allocated memory's segment */ int alloc_desc; /* Allocated memory's descriptor */ /* Check the title isn't too long */ if ((strlen(vmmtitle) + 1) > VMM_TITLE_BUFFER_LEN) return(-1); /* Allocate some DOS memory */ alloc_seg = __dpmi_allocate_dos_memory(VMM_TITLE_BUFFER_PARA, &alloc_desc); if (alloc_seg == -1) return(-1); /* Put the title in it */ movedata(_my_ds(), (int) vmmtitle, alloc_desc, 0, strlen(vmmtitle) + 1); /* Set up the registers - nuke DX as part of this; set AX to set the app title */ memset (&dpmi_regs, 0, sizeof(dpmi_regs)); dpmi_regs.x.ax = 0x168E; dpmi_regs.x.dx = 0x0001; dpmi_regs.x.es = alloc_seg; dpmi_regs.x.di = 0; /* Interrupt */ __dpmi_int (0x2F, &dpmi_regs); /* Free the memory */ __dpmi_free_dos_memory(alloc_desc); /* Return result */ if (dpmi_regs.x.ax != 0) return(0); /* Fail by default */ return(-1); } /* ------------------- - w95_getvmmtitle - ------------------- */ int w95_getvmmtitle (char *vmmtitle, int maxlen) { __dpmi_regs dpmi_regs; /* Registers for function call */ int alloc_seg; /* Allocated memory's segment */ int alloc_desc; /* Allocated memory's descriptor */ /* Allocate some DOS memory */ alloc_seg = __dpmi_allocate_dos_memory(VMM_TITLE_BUFFER_PARA, &alloc_desc); if (alloc_seg == -1) return(-1); /* Put the title in it */ //movedata(_my_ds(), (int) apptitle, alloc_desc, 0, strlen(apptitle) + 1); /* Set up the registers - nuke DX as part of this; set AX to set the app title */ memset (&dpmi_regs, 0, sizeof(dpmi_regs)); dpmi_regs.x.ax = 0x168E; dpmi_regs.x.dx = 0x0003; /* Get title */ dpmi_regs.x.cx = VMM_TITLE_BUFFER_LEN; /* Buffer size */ dpmi_regs.x.es = alloc_seg; /* Segment */ dpmi_regs.x.di = 0; /* Offset */ /* Interrupt */ __dpmi_int (0x2F, &dpmi_regs); /* Copy the string into apptitle - truncate it if there's not enough space */ if (maxlen > VMM_TITLE_BUFFER_LEN) maxlen = VMM_TITLE_BUFFER_LEN; movedata(alloc_desc, 0, _my_ds(), (int) vmmtitle, maxlen); vmmtitle[maxlen] = 0; /* Free the memory */ __dpmi_free_dos_memory(alloc_desc); /* Return result */ if (dpmi_regs.x.ax != 0) return(0); /* Fail by default */ return(-1); } -- ============================================================================== "You don't have to find the solution, you've got to understand the problem, and don't go hoping for a miracle." - 'Slight Return' by the Bluetones Rich Dawe - 3rd year Physicist @ Bristol Uni, UK E-mail: rd5718 AT bristol DOT ac DOT uk Web pages: http://irix.bris.ac.uk/~rd5718/ ==============================================================================