Message-ID: <32D192D7.4511@ix.netcom.com> Date: Mon, 06 Jan 1997 16:03:35 -0800 From: Dan Mintz Reply-To: danmintz AT ix DOT netcom DOT com Organization: Private Party MIME-Version: 1.0 To: djgpp AT delorie DOT com Subject: Re: Intel ASM to AT&T ASM question References: <01b9b9ca$9cccd040$aaf15ecf AT platko DOT ix DOT netcom DOT com> <5arf5r$lqn AT agate DOT berkeley DOT edu> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Eric J. Korpela wrote: > > In article <01b9b9ca$9cccd040$aaf15ecf AT platko DOT ix DOT netcom DOT com>, > Chuck Jarenski <3455245 AT popnet DOT ca DOT out DOT net> wrote: > >I'm trying to convert the following code from More Tricks of the > >Game-Programming Gurus into DJGPP. I'm having a problem getting the code > >in the book to work in the > >AT&T syntax. (Remember ScreenWidth is a 32bit int with the value of 640 > >and I am using near pointers with mem protection off.) > > > > void vputpixel(int x, int y, char color, char far *vscreen) > > { > > asm { > > push es > > mov ax,[y] > > mov bx,320 > > mul bx > > add ax,[x] > > les di,[vscreen] > > mov di,ax > > mov al,color > > stosb > > pop es > > } > > } > > Here I go into tirade mode. Not directed at you, but more toward > programming book writers in general. The big problem is that they > make novices think that a compiler is incapable of optimizing something > as simple as a putpixel routine. There is no reason to resort > to inline assembly. The above would translate as.... > > void vputpixel(int x, int y, char color, char *vscreen) > { > vscreen[y*320+x]=color; > } > > Run GCC on that and look at the output. Compare it to the above. GCC's > output is better! (Using mul to multiply by a constant! Get real!) > "Tricks of the Game Programming Gurus," heh. More like "Tricks of the > Writers Who Don't Know Anything About Programming." > > Exit Tirade mode.... > > >My AT&T code: > > > > void PutPixel(char *Buf, int X, int Y, char Color) > > { > > /* Places a pixel on the buffer at a X,Y location */ > > > > __asm__ __volatile__(" > > pushl %%es > > movl %0 , %%eax\n > > movl $_ScreenWidth, %%ebx\n > > mull %%ebx\n > > addl %1, %%eax\n > > lesl %2, %%edi\n > > movl %%eax, %%edi\n > > movb %%al, %3\n > > stosb\n > > popl %%ss" > > : > > : "g" (Y), "g" (X), "g" (Buf), "g" (Color) > > : "memory" > > ); > > } > > > > First hint, (as above) don't use assembly unless you have to. And for > putpixel, you don't have to. The above would work just fine as > > Buf[Y*ScreenWidth+X]=Color; > > Second, that multiply is expensive. If you can replace it by a constant, > do so. If you can't, you may want to define your graphics buffer as follows... > > typedef unsigned char pixel; > > typedef struct { > int width,height; > pixel **lines; > } GBuf; > > And create a buffer as follows.... > > GBuf *Create_GBuf(int width, int height) > { > int i; > GBuf *Buf=(GBuf *)calloc(1,sizeof(GBuf)+height*sizeof(pixel *)+ > width*height*sizeof(pixel)); > if (Buf) { > Buf->width=width; > Buf->height=height; > /* Warning, confusing pointer arithmetic. Look carefully.... */ > Buf->lines=Buf+1; > Buf->lines[0]=Buf->lines+height; > for (i=1;i Buf->lines[i]=Buf->lines[i-1]+width; > } > } > return (Buf); > } > > Then the putpixel function becomes.... > > void vputpixel(int x, int y, pixel color, GBuf *Buf) > /* This compiles to 5 instructions under SPARC */ > { > Buf->lines[y][x]=color; > } > > Voila, no more multiply! (Also, the routine easily changes to support > 16 or 32 bit color. Just change the pixel typedef.) (And it's portable!) > > Third hint. You are playing around with segment registers. Don't, unless > it's absolutely necessary. And if you do need to, load the register from > a dpmi or go32 variable like _go32_dos_ds or my_ds. > > Hope this helps. > > Eric > -- > Eric Korpela | An object at rest can never be > korpela AT ssl DOT berkeley DOT edu | stopped. > > Click here for more info. You're right! The writers did this to make money and didn't fully optimize their code. Take, for example, the vputpixel() function. A much faster way to do this would be through shifting with >> or <<. E-mail me if anyone wants the code for a FAST one. Dan