www.delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/2001/02/12/23:44:55

Message-ID: <000601c09577$53707660$168baad0@0021682320>
From: "Jeremiah" <xdebugx AT emeraldis DOT com>
To: <djgpp AT delorie DOT com>
References: <Pine DOT SUN DOT 3 DOT 91 DOT 1010212094219 DOT 12969L AT is> <96917s$guccd$1 AT ID-57378 DOT news DOT dfncis DOT de> <7263-Mon12Feb2001211331+0200-eliz AT is DOT elta DOT co DOT il> <003401c09558$17818a00$128baad0 AT 0021682320>
Subject: Re: inline asm
Date: Mon, 12 Feb 2001 23:42:07 -0500
MIME-Version: 1.0
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 5.50.4133.2400
X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400
Reply-To: djgpp AT delorie DOT com

----- Original Message -----
From: "Jeremiah" <xdebugx AT emeraldis DOT com>
To: <djgpp AT delorie DOT com>
Sent: Monday, February 12, 2001 7:58 PM
Subject: Re: inline asm


> > > From: "Alexei A. Frounze" <dummy_addressee AT hotmail DOT com>
> > > Newsgroups: comp.os.msdos.djgpp
> > > Date: Mon, 12 Feb 2001 11:00:07 -0500
> > > >
> > > > On Sun, 11 Feb 2001, Jeremiah wrote:
> > > >
> > > > > How do i call interrupts with inline assembly in djgpp compiler.
> like:
> > > > >  int 25h
> > > >
> > > > You don't need inline assembly for that, use __dpmi_int instead.
The
> > > > DJGPP FAQ shows how to do that in section 18.2 and other sections of
> > > > chapter 18.
> > > >
> > > > Issuing an INT instruction in assembly is not a good idea with
DJGPP,
> > > > since your program runs in protected mode, so the INT instruction is
> > > > handled by protected-mode handler first.  Who knows what that will
do?
> > >
> > > TechHelp says this (on int 31h fn 300h = simulate real-mode
interrupt):
> > > -------8<--------
> > > The DPMI host automatically handles all INT nn opcodes to provide
> > > BIOS and DOS services transparently.  I'm not sure why you would
> > > use this fn.
> > > -------8<--------
> > > So what's the problem?
> >
> > If this is what TechHelp says, perhaps you should toss it and read the
> > DJGPP FAQ (sections 18.1 and 18.2) instead ;-)  ``References'' like
> > this really make a disservice to a programmer by proliferating
> > disinformation.
> >
> > First of all, Int 25h requires a pointer to a buffer in DS:BX, and the
> > buffer needs to be in the low memory (below 1MB mark), since real-mode
> > addressing cannot reach higher addresses.  In contrast, a protected-mode
> > program has all its buffers above 1MB mark--problem no.1.
> >
> > In addition, different DPMI environments have different exciting
> > problems with specific interrupts when they are invoked as INT nn
> > instruction in protected mode.  For example, Int 2Fh, if issued in
> > protected mode on certain configurations of Windows 9X wedges the DOS
> > box so hard that the only thing you can do is kill the VM--problem no.2.
> >
> > Going through function 300h of Int 31h (i.e. via __dpmi_int) does not
> > have all these problems.
> >
> > In other words, Int 31h/AX=0300h was _designed_ to handle real-mode
> > interrupts, and the designers intended that programs will use it to
> > call real-mode services.  By contrast, INT nn issued in protected mode
> > was _never_ designed to handle real-mode services, so they work or
> > don't work by sheer coincidence, luck, or the lack thereof.
> >
> So how do i call intrupt 25h.  Is there a way to make djgpp run in real
> mode.  Or do i use __dpmi_int instead and if so do i use inline asm to set
> the bx, cx and dx registers that this intterupt uses, and what the syntax
> for using __dpmi_int?
>
Ok.  I took a look at the faq.  I got some questions about the code it
presents.

char * local_currency (void)
 {
   __dpmi_regs regs;

   regs.x.ax = 0x3800;        /* AH = 38h, AL = 00h  */
   regs.x.ds = __tb >> 4;     /* transfer buffer address in DS:DX  */
   regs.x.dx = __tb & 0x0f;
   __dpmi_int (0x21, &regs);  /* call DOS  */
   if (regs.x.flags & 1)      /* is carry flag set?  */
     /* The call failed; use the default symbol.  */
     return strdup ("$");
   else
     {
       /* The call succeeded.  The local currency symbol is stored
          as an ASCIIZ string at offset 2 in the transfer buffer.  */
       char *p = (char *)malloc (2);
       if (p != 0)
         dosmemget (__tb + 2, 2, p);
       return p;
     }

It says it puts the string at offset 2 int the transfer buffer.  Does it
always start the data at offset 2?   On: dosmemget (__tb +2,2,p);  is the
second 2 the number of bytes to put into p?

- Raw text -


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