delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/12/28/11:35:06

From: Gertjan Klein <gklein AT xs4all DOT nl>
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

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 <stdio.h>

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 <gklein AT xs4all DOT nl>
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/
==============================================================================

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019