Replace invalid characters with HTML entities
— with — ’ with ’ + with + × with x ç with ç “ with “ ” with ” ‘ with ‘ • with • – with - µ with µ † with † Fix C++ θ with θ Yen symbol instead of times Fix broken apos Bullet again E-circumflex
This commit is contained in:
parent
9e52de9586
commit
500e7f5654
353 changed files with 5091 additions and 5091 deletions
62
16-02.html
62
16-02.html
|
|
@ -36,13 +36,13 @@
|
|||
</TABLE>
|
||||
</CENTER>
|
||||
<P><BR></P>
|
||||
<P>Listing 16.2 is Listing 16.1 modified to call a function that scans each block for words, and Listing 16.3 contains an assembly function that counts words. Used together, Listings 16.2 and 16.3 are just about twice as fast as Listing 16.1, a good return for a little assembly language. Listing 16.3 is a pretty straightforward translation from C to assembly; the new code makes good use of registers, but the key code—determining whether each byte is a character or not—is still done with the same multiple-sequential-tests approach used by the code that the C compiler generates.
|
||||
<P>Listing 16.2 is Listing 16.1 modified to call a function that scans each block for words, and Listing 16.3 contains an assembly function that counts words. Used together, Listings 16.2 and 16.3 are just about twice as fast as Listing 16.1, a good return for a little assembly language. Listing 16.3 is a pretty straightforward translation from C to assembly; the new code makes good use of registers, but the key code—determining whether each byte is a character or not—is still done with the same multiple-sequential-tests approach used by the code that the C compiler generates.
|
||||
</P>
|
||||
<P><B>LISTING 16.2 L16-2.C</B></P>
|
||||
<!-- CODE //-->
|
||||
<PRE>
|
||||
/* Word-counting program incorporating assembly language. Tested
|
||||
with Borland C<SMALL>++</SMALL> in C compilation mode & the small model. */
|
||||
with Borland C<SMALL>++</SMALL> in C compilation mode & the small model. */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
|
|
@ -63,22 +63,22 @@
|
|||
char *Buffer, CharFlag = 0;
|
||||
|
||||
if (argc != 2) {
|
||||
printf(“usage: wc <filename>\n”);
|
||||
printf(“usage: wc <filename>\n”);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((Buffer = malloc(BUFFER_SIZE)) == NULL) {
|
||||
printf(“Can’t allocate adequate memory\n”);
|
||||
printf(“Can’t allocate adequate memory\n”);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((Handle = open(argv[1], O_RDONLY | O_BINARY)) == -1) {
|
||||
printf(“Can’t open file %s\n”, argv[1]);
|
||||
printf(“Can’t open file %s\n”, argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if ((FileSize = filelength(Handle)) == -1) {
|
||||
printf(“Error sizing file %s\n”, argv[1]);
|
||||
printf(“Error sizing file %s\n”, argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
@ -86,7 +86,7 @@
|
|||
while (FileSize > 0) {
|
||||
FileSize -= (BlockSize = min(FileSize, BUFFER_SIZE));
|
||||
if (read(Handle, Buffer, BlockSize) == -1) {
|
||||
printf(“Error reading file %s\n”, argv[1]);
|
||||
printf(“Error reading file %s\n”, argv[1]);
|
||||
exit(1);
|
||||
}
|
||||
ScanBuffer(Buffer, BlockSize, &CharFlag, &WordCount);
|
||||
|
|
@ -94,9 +94,9 @@
|
|||
|
||||
/* Catch the last word, if any */
|
||||
if (CharFlag) {
|
||||
WordCount++;
|
||||
WordCount++;
|
||||
}
|
||||
printf(“\nTotal words in file: %lu\n”, WordCount);
|
||||
printf(“\nTotal words in file: %lu\n”, WordCount);
|
||||
return(0);
|
||||
}
|
||||
</PRE>
|
||||
|
|
@ -127,37 +127,37 @@
|
|||
.code
|
||||
public _ScanBuffer
|
||||
_ScanBuffer proc near
|
||||
push bp ;preserve caller’s stack frame
|
||||
push bp ;preserve caller’s stack frame
|
||||
mov bp,sp ;set up local stack frame
|
||||
push si ;preserve caller’s register vars
|
||||
push si ;preserve caller’s register vars
|
||||
push di
|
||||
|
||||
mov si,[bp+Buffer] ;point to buffer to scan
|
||||
mov bx,[bp+WordCount]
|
||||
mov si,[bp+Buffer] ;point to buffer to scan
|
||||
mov bx,[bp+WordCount]
|
||||
mov cx,[bx] ;get current 32-bit word count
|
||||
mov dx,[bx+2]
|
||||
mov bx,[bp+CharFlag]
|
||||
mov dx,[bx+2]
|
||||
mov bx,[bp+CharFlag]
|
||||
mov bl,[bx] ;get current CharFlag
|
||||
mov di,[bp+BufferLength];get # of bytes to scan
|
||||
mov di,[bp+BufferLength];get # of bytes to scan
|
||||
ScanLoop:
|
||||
mov bh,bl ;PredCharFlag = CharFlag;
|
||||
lodsb ;Ch = *BufferPtr++ & 0x7F;
|
||||
lodsb ;Ch = *BufferPtr++ & 0x7F;
|
||||
and al,7fh ;strip high bit for word processors
|
||||
; that set it as an internal flag
|
||||
mov bl,1 ;assume this is a char; CharFlag = 1;
|
||||
cmp al,‘a’ ;it is a char if between a and z
|
||||
cmp al,‘a’ ;it is a char if between a and z
|
||||
jb CheckAZ
|
||||
cmp al,‘z’
|
||||
cmp al,‘z’
|
||||
jna IsAChar
|
||||
CheckAZ:
|
||||
cmp al,‘A’ ;it is a char if between A and Z
|
||||
cmp al,‘A’ ;it is a char if between A and Z
|
||||
jb Check09
|
||||
cmp al,‘Z’
|
||||
cmp al,‘Z’
|
||||
jna IsAChar
|
||||
Check09:
|
||||
cmp al,‘0’ ;it is a char if between 0 and 9
|
||||
cmp al,‘0’ ;it is a char if between 0 and 9
|
||||
jb CheckApostrophe
|
||||
cmp al,‘9’
|
||||
cmp al,‘9’
|
||||
jna IsAChar
|
||||
CheckApostrophe:
|
||||
cmp al,27h ;it is a char if an apostrophe
|
||||
|
|
@ -165,29 +165,29 @@
|
|||
sub bl,bl ;not a char; CharFlag = 0;
|
||||
and bh,bh
|
||||
jz ScanLoopBottom ;if ((!CharFlag) && PredCharFlag) {
|
||||
add cx,1 ; (WordCount)++;
|
||||
add cx,1 ; (WordCount)++;
|
||||
adc dx,0 ;}
|
||||
IsAChar:
|
||||
ScanLoopBottom:
|
||||
dec di ;} while (—BufferLength);
|
||||
dec di ;} while (—BufferLength);
|
||||
jnz ScanLoop
|
||||
|
||||
mov si,[bp+CharFlag]
|
||||
mov si,[bp+CharFlag]
|
||||
mov [si],bl ;set new CharFlag
|
||||
mov bx,[bp+WordCount]
|
||||
mov bx,[bp+WordCount]
|
||||
mov [bx],cx ;set new word count
|
||||
mov [bx+2],dx
|
||||
mov [bx+2],dx
|
||||
|
||||
pop di ;restore caller’s register vars
|
||||
pop di ;restore caller’s register vars
|
||||
pop si
|
||||
pop bp ;restore caller’s stack frame
|
||||
pop bp ;restore caller’s stack frame
|
||||
ret
|
||||
_ScanBuffer endp
|
||||
end
|
||||
</PRE>
|
||||
<!-- END CODE //-->
|
||||
<H4 ALIGN="LEFT"><A NAME="Heading4"></A><FONT COLOR="#000077">Which Way to Go from Here?</FONT></H4>
|
||||
<P>We could rearrange the tests in light of the nature of the data being scanned; for example, we could perform the tests more efficiently by taking advantage of the knowledge that if a byte is less than ‘0,’ it’s either an apostrophe or not a character at all. However, that sort of fine-tuning is typically good for speedups of only 10 to 20 percent, and I’ve intentionally refrained from implementing this in Listing 16.3 to avoid pointing you down the wrong path; what we need is a different tack altogether. Ponder this. What we <I>really</I> want to know is nothing more than whether a byte is a character, not what sort of character it is. For each byte value, we want a yes/no status, and nothing else—and that description practically begs for a lookup table. Listing 16.4 uses a lookup table approach to boost performance another 50 percent, to three times the performance of the original C code. On a 20 MHz 386, this represents a change from 4.6 to 1.6 seconds, which could be significant—who likes to wait? On an 8088, the improvement in word-counting a large file could easily be 10 or 20 seconds, which is <I>definitely</I> significant.</P><P><BR></P>
|
||||
<P>We could rearrange the tests in light of the nature of the data being scanned; for example, we could perform the tests more efficiently by taking advantage of the knowledge that if a byte is less than ‘0,’ it’s either an apostrophe or not a character at all. However, that sort of fine-tuning is typically good for speedups of only 10 to 20 percent, and I’ve intentionally refrained from implementing this in Listing 16.3 to avoid pointing you down the wrong path; what we need is a different tack altogether. Ponder this. What we <I>really</I> want to know is nothing more than whether a byte is a character, not what sort of character it is. For each byte value, we want a yes/no status, and nothing else—and that description practically begs for a lookup table. Listing 16.4 uses a lookup table approach to boost performance another 50 percent, to three times the performance of the original C code. On a 20 MHz 386, this represents a change from 4.6 to 1.6 seconds, which could be significant—who likes to wait? On an 8088, the improvement in word-counting a large file could easily be 10 or 20 seconds, which is <I>definitely</I> significant.</P><P><BR></P>
|
||||
<CENTER>
|
||||
<TABLE BORDER>
|
||||
<TR>
|
||||
|
|
|
|||
Loading…
Reference in a new issue