Mail Archives: djgpp/1998/01/03/14:44:14
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 -