Use backtick code blocks for syntax highlighting

This commit is contained in:
James Gregory 2013-12-31 11:38:48 +11:00
commit f658bfbb40
203 changed files with 26546 additions and 25801 deletions

280
16-02.md
View file

@ -22,147 +22,151 @@ generates.
**LISTING 16.2 L16-2.C**
/* Word-counting program incorporating assembly language. Tested
with Borland C++ in C compilation mode & the small model. */
#include <stdio.h>
#include <fcntl.h>
#include <sys\stat.h>
#include <stdlib.h>
#include <io.h>
#define BUFFER_SIZE 0x8000 /* largest chunk of file worked
with at any one time */
int main(int, char **);
void ScanBuffer(char *, unsigned int, char *, unsigned long *);
int main(int argc, char **argv) {
int Handle;
unsigned int BlockSize;
long FileSize;
unsigned long WordCount = 0;
char *Buffer, CharFlag = 0;
if (argc != 2) {
printf("usage: wc <filename>\n");
exit(1);
}
if ((Buffer = malloc(BUFFER_SIZE)) == NULL) {
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]);
exit(1);
}
if ((FileSize = filelength(Handle)) == -1) {
printf("Error sizing file %s\n", argv[1]);
exit(1);
}
CharFlag = 0;
while (FileSize > 0) {
FileSize -= (BlockSize = min(FileSize, BUFFER_SIZE));
if (read(Handle, Buffer, BlockSize) == -1) {
printf("Error reading file %s\n", argv[1]);
exit(1);
}
ScanBuffer(Buffer, BlockSize, &CharFlag, &WordCount);
}
/* Catch the last word, if any */
if (CharFlag) {
WordCount++;
}
printf("\nTotal words in file: %lu\n", WordCount);
return(0);
}
```c
/* Word-counting program incorporating assembly language. Tested
with Borland C++ in C compilation mode & the small model. */
#include <stdio.h>
#include <fcntl.h>
#include <sys\stat.h>
#include <stdlib.h>
#include <io.h>
#define BUFFER_SIZE 0x8000 /* largest chunk of file worked
with at any one time */
int main(int, char **);
void ScanBuffer(char *, unsigned int, char *, unsigned long *);
int main(int argc, char **argv) {
int Handle;
unsigned int BlockSize;
long FileSize;
unsigned long WordCount = 0;
char *Buffer, CharFlag = 0;
if (argc != 2) {
printf("usage: wc <filename>\n");
exit(1);
}
if ((Buffer = malloc(BUFFER_SIZE)) == NULL) {
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]);
exit(1);
}
if ((FileSize = filelength(Handle)) == -1) {
printf("Error sizing file %s\n", argv[1]);
exit(1);
}
CharFlag = 0;
while (FileSize > 0) {
FileSize -= (BlockSize = min(FileSize, BUFFER_SIZE));
if (read(Handle, Buffer, BlockSize) == -1) {
printf("Error reading file %s\n", argv[1]);
exit(1);
}
ScanBuffer(Buffer, BlockSize, &CharFlag, &WordCount);
}
/* Catch the last word, if any */
if (CharFlag) {
WordCount++;
}
printf("\nTotal words in file: %lu\n", WordCount);
return(0);
}
```
**LISTING 16.3 L16-3.ASM**
; Assembly subroutine for Listing 16.2. Scans through Buffer, of
; length BufferLength, counting words and updating WordCount as
; appropriate. BufferLength must be > 0. *CharFlag and *WordCount
; should equal 0 on the first call. Tested with TASM.
; C near-callable as:
; void ScanBuffer(char *Buffer, unsigned int BufferLength,
; char *CharFlag, unsigned long *WordCount);
parms struc
dw 2 dup(?) ;pushed return address & BP
Buffer dw ? ;buffer to scan
BufferLength dw ? ;length of buffer to scan
CharFlag dw ? ;pointer to flag for state of last
; char processed on entry (0 on
; initial call). Updated on exit
WordCount dw ? ;pointer to 32-bit count of words
; found (0 on initial call)
parms ends
.model small
.code
public _ScanBuffer
_ScanBuffer proc near
push bp ;preserve caller's stack frame
mov bp,sp ;set up local stack frame
push si ;preserve caller's register vars
push di
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 bl,[bx] ;get current CharFlag
mov di,[bp+BufferLength];get # of bytes to scan
ScanLoop:
mov bh,bl ;PredCharFlag = CharFlag;
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
jb CheckAZ
cmp al,‘z'
jna IsAChar
CheckAZ:
cmp al,‘A' ;it is a char if between A and Z
jb Check09
cmp al,‘Z'
jna IsAChar
Check09:
cmp al,‘0' ;it is a char if between 0 and 9
jb CheckApostrophe
cmp al,‘9'
jna IsAChar
CheckApostrophe:
cmp al,27h ;it is a char if an apostrophe
jz IsAChar
sub bl,bl ;not a char; CharFlag = 0;
and bh,bh
jz ScanLoopBottom ;if ((!CharFlag) && PredCharFlag) {
add cx,1 ; (WordCount)++;
adc dx,0 ;}
IsAChar:
ScanLoopBottom:
dec di ;} while (—BufferLength);
jnz ScanLoop
mov si,[bp+CharFlag]
mov [si],bl ;set new CharFlag
mov bx,[bp+WordCount]
mov [bx],cx ;set new word count
mov [bx+2],dx
pop di ;restore caller's register vars
pop si
pop bp ;restore caller's stack frame
ret
_ScanBuffer endp
end
```nasm
; Assembly subroutine for Listing 16.2. Scans through Buffer, of
; length BufferLength, counting words and updating WordCount as
; appropriate. BufferLength must be > 0. *CharFlag and *WordCount
; should equal 0 on the first call. Tested with TASM.
; C near-callable as:
; void ScanBuffer(char *Buffer, unsigned int BufferLength,
; char *CharFlag, unsigned long *WordCount);
parms struc
dw 2 dup(?) ;pushed return address & BP
Buffer dw ? ;buffer to scan
BufferLength dw ? ;length of buffer to scan
CharFlag dw ? ;pointer to flag for state of last
; char processed on entry (0 on
; initial call). Updated on exit
WordCount dw ? ;pointer to 32-bit count of words
; found (0 on initial call)
parms ends
.model small
.code
public _ScanBuffer
_ScanBuffer proc near
push bp ;preserve caller's stack frame
mov bp,sp ;set up local stack frame
push si ;preserve caller's register vars
push di
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 bl,[bx] ;get current CharFlag
mov di,[bp+BufferLength];get # of bytes to scan
ScanLoop:
mov bh,bl ;PredCharFlag = CharFlag;
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
jb CheckAZ
cmp al,‘z'
jna IsAChar
CheckAZ:
cmp al,‘A' ;it is a char if between A and Z
jb Check09
cmp al,‘Z'
jna IsAChar
Check09:
cmp al,‘0' ;it is a char if between 0 and 9
jb CheckApostrophe
cmp al,‘9'
jna IsAChar
CheckApostrophe:
cmp al,27h ;it is a char if an apostrophe
jz IsAChar
sub bl,bl ;not a char; CharFlag = 0;
and bh,bh
jz ScanLoopBottom ;if ((!CharFlag) && PredCharFlag) {
add cx,1 ; (WordCount)++;
adc dx,0 ;}
IsAChar:
ScanLoopBottom:
dec di ;} while (—BufferLength);
jnz ScanLoop
mov si,[bp+CharFlag]
mov [si],bl ;set new CharFlag
mov bx,[bp+WordCount]
mov [bx],cx ;set new word count
mov [bx+2],dx
pop di ;restore caller's register vars
pop si
pop bp ;restore caller's stack frame
ret
_ScanBuffer endp
end
```
#### Which Way to Go from Here? {#Heading4}