delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1997/08/26/14:31:17

Date: Tue, 26 Aug 1997 11:30:32 -0700 (PDT)
Message-Id: <199708261830.LAA11093@adit.ap.net>
Mime-Version: 1.0
To: firewind <firewind AT metroid DOT dyn DOT ml DOT org>, djgpp AT delorie DOT com
From: Nate Eldredge <eldredge AT ap DOT net>
Subject: Re: [Q] using int 0x21 to print text with inline asm
Cc: eggbrains AT aol DOT com

At 11:35  8/25/1997 GMT, firewind wrote:
>Egg brains <eggbrains AT aol DOT com> wrote:
>> char *myHappy;      /* i have also tried using a character */
>  ^^^^^^^^^^^^^^ (1)
>> void main()
>  ^^^^^^^^^^^ (2)
>> {
>
>> myHappy = "Hello, world!";
>  ^^^^^^^^^^^^^^^^^^^^^^^^^^ (3)
>> asm("movw _myHappy, %dx");
>> asm("movb $9, %ah");
>> asm("int $0x21");       
>> }
>1: No memory is allocated that this pointer points to.
It doesn't need to be. It's initialized to point to the constant "Hello,
world!" somewhere in the data space.
>2: main() -always- returns an int.
True. It also takes args (void) or (int argc, char *argv[]). (char **argv
also works, AFAIK, but no flames if I'm wrong.)
>3: you're assiging a string to a variable, but this string really has no
>   storage allocated for it.
Not true. The address of the string, which is compiled into the binary, is
assigned to the pointer variable myHappy. It's read-only, of course (unless
you used the writable-strings compiler switch), but other than that, it's
perfectly legal and correct.

All this dodges the real problem, which is that your program runs in
protected mode, and the address of the string is a 32-bit pointer relative
to the program's DS. The DOS INT 21h function expects a real-mode address,
with 16-bit segment and offset. You are giving it the protected-mode DS
selector, and what seems to be either the low or high half of the string's
32-bit address. The contents of this address in conventional memory are
god-knows-what.
Another problem is that INT 21h function 9 wants a `$'-terminated string (a
holdover from CPM days). You should be initializing myHappy to "Hello, world!$".
Furthermore, the asm instruction "int $0x21" generates an INT 21h in
*protected mode*. If it's handled there, it will never get to real mode and
DOS. This is obviously not your problem currently, and is probably unlikely
to occur, but it's a bad idea all the same.

So. If you really want to use DOS function 9 to print a string:
- `$'-terminate it.
- Move it to somewhere in conventional memory, either the transfer buffer or
a chunk you've allocated with __dpmi_allocate_dos_memory.
- Use __dpmi_int to call INT 21, and be sure to use the address of the
conventional memory copy of the string.

HTH

Nate Eldredge
eldredge AT ap DOT net



- Raw text -


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