Use backtick code blocks for syntax highlighting
This commit is contained in:
parent
8ed9dea394
commit
f658bfbb40
203 changed files with 26546 additions and 25801 deletions
280
16-02.md
280
16-02.md
|
|
@ -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}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue