Date: Sat, 3 Jan 1998 11:40:22 -0800 (PST) Message-Id: <199801031940.LAA26880@adit.ap.net> Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii" To: Nat Saiger , djgpp AT delorie DOT com From: Nate Eldredge Subject: Re: Simple Assembly Question Precedence: bulk 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