delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp/1998/01/03/14:44:14

Date: Sat, 3 Jan 1998 11:40:22 -0800 (PST)
Message-Id: <199801031940.LAA26880@adit.ap.net>
Mime-Version: 1.0
To: Nat Saiger <lunchbox AT stayfree DOT co DOT uk>, djgpp AT delorie DOT com
From: Nate Eldredge <eldredge AT ap DOT net>
Subject: Re: Simple Assembly Question

At 05:36  1/3/1998 +0000, Nat Saiger wrote:
>Hi,
>
>    Being new to both DJGPP and AT&T syntax asm, i'm having difficulties
>implementing both inline and external assembly.
>
>    This is what i'm trying to convert  (in BCC and inline Intel):
>
>                void Blit(char *source, char *dest)
>                {
>                    asm{
>                            push ds
>                            les di,dest
>                            lds si,source
>                            mov cx,32768
>                            rep movsw
>                            pop ds
>                            }
>                    }
>
>This is how I converted it...
>
>void (char *source, char *dest)
>{
>        short global_selector = _dos_ds;
>        asm("
>                 pushl %eds
>                 movw _global_selector, %es
>                 movl _dest, %edi
>                 movw _global_selector, %ds
>                 movl _source,%esi                  // my intel syntax
>book says %esi exists, the assembler
>                 movl $32768, %ecx                // disagrees
>                 rep  movsw
>                 popl %eds
>             ")
>}
A few problems.
* There is no such register as %eds. `pushl' works on word segment registers
directly.
* You load both %es and %ds from _dos_ds. I doubt this is what you want to
do. If both operands should be in your address space (and since they are
pointers I assume they are), the value to use is `_my_ds()', but %ds and %es
always contain it by default, and in fact must.
* You can't access local variables by prepending an underscore. You have to
use GCC's extended assembly features.
>
>When I compile it I get "Opcodes match no known 386 instruction" but it
>doesn't tell me which line is causing the error.
>I've read the FAQ's and also a document on AT&T syntax and it ain't much
>help
>If someone could do a working conversion for me, (and possibly an
>external version), I would be very grateful.
Here's a probably very overcomplicated one. :) It takes both args as
pointers within your address space. If you want to blit to video memory, you
must load %es with _dos_ds, and set the destination to a real-mode linear
address.

void blit(char *src, char *dest)
{
   asm volatile ("rep; movsl"
                 : /* no outputs */
                 : "S" (src), /* load src into %esi */
                   "D" (dest), /* load dest into %edi */
                   "c" (32768 / 2) /* load %ecx with count */
                                   /* divide by 2 since we move 32 bits */
                 );
}

Incidentally, you can also use `memcpy' for this which should be nearly as
fast. `movedata' will work if you want to move between segments (like to
conventional memory).

Nate Eldredge
eldredge AT ap DOT net



- Raw text -


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