151 lines
7.2 KiB
HTML
151 lines
7.2 KiB
HTML
<HTML>
|
|
<HEAD>
|
|
<META name=vsisbn content="1576101746">
|
|
<META name=vstitle content="Michael Abrash's Graphics Programming Black Book, Special Edition">
|
|
<META name=vsauthor content="Michael Abrash">
|
|
<META name=vspublisher content="The Coriolis Group">
|
|
<META name=vspubdate content="07/01/97">
|
|
<META name=vscategory content="Web and Software Development: Game Development,Web and Software Development: Graphics and Multimedia Development">
|
|
|
|
|
|
|
|
|
|
|
|
|
|
<TITLE>Michael Abrash's Graphics Programming Black Book Special Edition: Zenning and the Flexible Mind</TITLE>
|
|
|
|
<!-- HEADER -->
|
|
<!-- Empty Reference Subhead -->
|
|
|
|
<!--ISBN=1576101746//-->
|
|
<!--TITLE=Michael Abrash's Graphics Programming Black Book Special Edition//-->
|
|
<!--AUTHOR=Michael Abrash//-->
|
|
<!--PUBLISHER=The Coriolis Group, Inc.//-->
|
|
<!--CHAPTER=22//-->
|
|
<!--PAGES=417-418//-->
|
|
<!--UNASSIGNED1//-->
|
|
<!--UNASSIGNED2//--></HEAD><BODY LINK=#0000FF ALINK=#000099 VLINK=#0000FF BGCOLOR=#FFFFFF>
|
|
|
|
<CENTER>
|
|
<TABLE BORDER>
|
|
<TR>
|
|
<TD><A HREF="22-01.html">Previous</A></TD>
|
|
<TD><A HREF="index.html">Table of Contents</A></TD>
|
|
<TD><A HREF="22-03.html">Next</A></TD>
|
|
</TR>
|
|
</TABLE>
|
|
</CENTER>
|
|
<P><BR></P>
|
|
<P><B>LISTING 22.2 L22-2.ASM</B></P>
|
|
<!-- CODE //-->
|
|
<PRE>
|
|
ClearS proc near
|
|
push bp ;save caller’s BP
|
|
mov bp,sp ;point to stack frame
|
|
cmp word ptr [bp].BufSeg,0 ;skip the fill if a null
|
|
jne Start ; pointer is passed
|
|
cmp word ptr [bp].BufOfs,0
|
|
je Bye
|
|
Start: cld ;make STOSW count up
|
|
mov ax,[bp].Attrib ;load AX with attribute parameter
|
|
and ax,0ff00h ;prepare for merging with fill char
|
|
mov bx,[bp].Filler ;load BX with fill char
|
|
and bx,0ffh ;prepare for merging with attribute
|
|
or ax,bx ;combine attribute and fill char
|
|
mov di,[bp].BufOfs ;load DI with target buffer offset
|
|
mov es,[bp].BufSeg ;load ES with target buffer segment
|
|
mov cx,[bp].BufSize ;load CX with buffer size
|
|
rep stosw ;fill the buffer
|
|
Bye:
|
|
pop bp ;restore caller’s BP
|
|
ret EndMrk-RetAddr-2 ;return, clearing the parms from the stack
|
|
ClearS endp
|
|
</PRE>
|
|
<!-- END CODE //-->
|
|
<P>(The <B>OnStack</B> structure definition doesn’t change in any of our examples, so I’m not going clutter up this chapter by reproducing it for each new version of <B>ClearS</B>.)</P>
|
|
<P>Okay, loading ES and DI directly saves another four bytes. We’ve squeezed a total of 6 bytes—about 11 percent—out of <B>ClearS</B>. What next?</P>
|
|
<P>Well, <B>LES</B> would serve better than two <B>MOV</B> instructions for loading ES and DI as shown in Listing 22.3.</P>
|
|
<P><B>LISTING 22.3 L22-3.ASM</B></P>
|
|
<!-- CODE //-->
|
|
<PRE>
|
|
ClearS proc near
|
|
push bp ;save caller’s BP
|
|
mov bp,sp ;point to stack frame
|
|
cmp word ptr [bp].BufSeg,0 ;skip the fill if a null
|
|
jne Start ; pointer is passed
|
|
cmp word ptr [bp].BufOfs,0
|
|
je Bye
|
|
Start: cld ;make STOSW count up
|
|
mov ax,[bp].Attrib ;load AX with attribute parameter
|
|
and ax,0ff00h ;prepare for merging with fill char
|
|
mov bx,[bp].Filler ;load BX with fill char
|
|
and bx,0ffh ;prepare for merging with attribute
|
|
or ax,bx ;combine attribute and fill char
|
|
les di,dword ptr [bp].BufOfs ;load ES:DI with target buffer
|
|
;segment:offset
|
|
mov cx,[bp].BufSize ;load CX with buffer size
|
|
rep stosw ;fill the buffer
|
|
Bye:
|
|
pop bp ;restore caller’s BP
|
|
ret EndMrk-RetAddr-2 ;return, clearing the parms from the stack
|
|
ClearS endp
|
|
</PRE>
|
|
<!-- END CODE //-->
|
|
<P>That’s good for another three bytes. We’re down to 43 bytes, and counting.
|
|
</P>
|
|
<P>We can save 3 more bytes by clearing the low and high bytes of AX and BX, respectively, by using <B>SUB <I>reg8,reg8</I></B> rather than ANDing 16-bit values as shown in Listing 22.4.</P>
|
|
<P><B>LISTING 22.4 L22-4.ASM</B></P>
|
|
<!-- CODE //-->
|
|
<PRE>
|
|
ClearS proc near
|
|
push bp ;save caller’s BP
|
|
mov bp,sp ;point to stack frame
|
|
cmp word ptr [bp].BufSeg,0 ;skip the fill if a null
|
|
jne Start ; pointer is passed
|
|
cmp word ptr [bp].BufOfs,0
|
|
je Bye
|
|
Start: cld ;make STOSW count up
|
|
mov ax,[bp].Attrib ;load AX with attribute parameter
|
|
sub al,al ;prepare for merging with fill char
|
|
mov bx,[bp].Filler ;load BX with fill char
|
|
sub bh,bh ;prepare for merging with attribute
|
|
or ax,bx ;combine attribute and fill char
|
|
les di,dword ptr [bp].BufOfs ;load ES:DI with target buffer
|
|
;segment:offset
|
|
mov cx,[bp].BufSize ;load CX with buffer size
|
|
rep stosw ;fill the buffer
|
|
Bye:
|
|
pop bp ;restore caller’s BP
|
|
ret EndMrk-RetAddr-2 ;return, clearing the parms from the stack
|
|
ClearS endp
|
|
</PRE>
|
|
<!-- END CODE //-->
|
|
<P>Now we’re down to 40 bytes—more than 20 percent smaller than the original code. That’s pretty much it for simple instruction optimizations. Now let’s look for instruction optimizations.
|
|
</P>
|
|
<P>It seems strange to load a word value into AX and then throw away AL. Likewise, it seems strange to load a word value into BX and then throw away BH. However, those steps are necessary because the two modified word values are ORed into a single character/attribute word value that is then used to fill the target buffer.</P>
|
|
<P>Let’s step back and see what this code really <I>does</I>, though. All it does in the end is load one byte addressed relative to BP into AH and another byte addressed relative to BP into AL. Heck, we can just do that directly! Presto—we’ve saved another 6 bytes, and turned two word-sized memory accesses into byte-sized memory accesses as well. Listing 22.5 shows the new code.</P><P><BR></P>
|
|
<CENTER>
|
|
<TABLE BORDER>
|
|
<TR>
|
|
<TD><A HREF="22-01.html">Previous</A></TD>
|
|
<TD><A HREF="index.html">Table of Contents</A></TD>
|
|
<TD><A HREF="22-03.html">Next</A></TD>
|
|
</TR>
|
|
</TABLE>
|
|
</CENTER>
|
|
|
|
<hr width="90%" size="1" noshade>
|
|
<div align="center">
|
|
<font face="Verdana,sans-serif" size="1">Graphics Programming Black Book © 2001 Michael Abrash</font>
|
|
</div>
|
|
<!-- all of the reference materials (books) have the footer and subfoot reveresed -->
|
|
<!-- reference_subfoot = footer -->
|
|
<!-- reference_footer = subfoot -->
|
|
|
|
<!-- BEGIN SUB FOOTER -->
|
|
</BODY>
|
|
</HTML>
|
|
|
|
<!-- END FOOTER -->
|
|
|
|
|