home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Simtel MSDOS 1992 September
/
Simtel20_Sept92.cdr
/
msdos
/
ddjmag
/
ddj9003.arc
/
ABRASH.LST
next >
Wrap
File List
|
1990-02-13
|
9KB
|
254 lines
ASSEMBLY LANGUAGE LIVES!
by Michael Abrash
[LISTING ONE]
/* Sample program to copy one far string to another far string,
* converting lower case letters to upper case letters in the process. */
#include <ctype.h>
char Source[] = "AbCdEfGhIjKlMnOpQrStUvWxYz0123456789!";
char Dest[100];
/*
* Copies one far string to another far string, converting all lower
* case letters to upper case before storing them.
*/
void CopyUppercase(char far *DestPtr, char far *SourcePtr) {
char UpperSourceTemp;
do {
/* Using UpperSourceTemp avoids a second load of the far pointer
SourcePtr as the toupper macro is expanded */
UpperSourceTemp = *SourcePtr++;
*DestPtr++ = toupper(UpperSourceTemp);
} while (UpperSourceTemp);
}
main() {
CopyUppercase((char far *)Dest,(char far *)Source);
}
[LISTING TWO
; C near-callable subroutine, callable as:
; void CopyUppercase(char far *DestPtr, char far *SourcePtr);
;
; Copies one far string to another far string, converting all lower
; case letters to upper case before storing them. Strings must be
; zero-terminated.
;
parms struc
dw ? ;pushed BP
dw ? ;return address
DestPtr dd ? ;destination string
SourcePtr dd ? ;source string
parms ends
;
.model small
.code
public _CopyUppercase
_CopyUppercase proc near
push bp
mov bp,sp ;set up stack frame
push si ;preserve C's register vars
push di
;
push ds ;we'll point DS to source
; segment for the duration
; of the loop
les di,[bp+DestPtr] ;point ES:DI to destination
lds si,[bp+SourcePtr] ;point DS:SI to source
CopyAndConvertLoop:
lodsb ;get next source byte
cmp al,'a' ;is it lower case?
jb SaveUpper ;no
cmp al,'z' ;is it lower case?
ja SaveUpper ;no
and al,not 20h ;convert to upper case
SaveUpper:
stosb ;store the byte to the dest
and al,al ;is this the terminating 0?
jnz CopyAndConvertLoop ;if not, repeat loop
;
pop ds ;restore caller's DS
;
pop di ;restore C's register vars
pop si
pop bp ;restore caller's stack frame
ret
_CopyUppercase endp
end
[LISTING THREE]
/* Sample program to copy one near string to another near string,
* converting lower case letters to upper case letters in the process. *
/
#include <ctype.h>
char Source[] = "AbCdEfGhIjKlMnOpQrStUvWxYz0123456789!";
char Dest[100];
/*
* Copies one near string to another near string, converting all lower
* case letters to upper case before storing them.
*/
void CopyUppercase(char *DestPtr, char *SourcePtr) {
char UpperSourceTemp;
do {
/* Using UpperSourceTemp allows slightly better optimization
than using *SourcePtr directly */
UpperSourceTemp = *SourcePtr++;
*DestPtr++ = toupper(UpperSourceTemp);
} while (UpperSourceTemp);
}
main() {
CopyUppercase(Dest,Source);
}
[LISTING FOUR]
; C near-callable subroutine, callable as:
; void CopyUppercase(char *DestPtr, char *SourcePtr);
;
; Copies one near string to another near string, converting all lower
; case letters to upper case before storing them. Strings must be
; zero-terminated.
;
parms struc
dw ? ;pushed BP
dw ? ;return address
DestPtr dw ? ;destination string
SourcePtr dw ? ;source string
parms ends
;
.model small
.code
public _CopyUppercase
_CopyUppercase proc near
push bp
mov bp,sp ;set up stack frame
push si ;preserve C's register vars
push di
;
mov di,[bp+DestPtr] ;point DI to destination
mov si,[bp+SourcePtr] ;point SI to source
mov cx,('a' shl 8) + 'z' ;preload CH with lower end of
; lower case range and CL with
; upper end of that range
mov bl,not 20h ;preload BL with value used to
; convert to upper case
CopyAndConvertLoop:
lodsw ;get next two source bytes
cmp al,ch ;is the 1st byte lower case?
jb SaveUpper ;no
cmp al,cl ;is the 1st byte lower case?
ja SaveUpper ;no
and al,bl ;convert 1st byte to upper case
SaveUpper:
and al,al ;is the 1st byte the
; terminating 0?
jz SaveLastAndDone ;yes, save it & done
cmp ah,ch ;is the 2nd byte lower case?
jb SaveUpper2 ;no
cmp ah,cl ;is the 2nd byte lower case?
ja SaveUpper2 ;no
and ah,bl ;convert 2nd byte to upper case
SaveUpper2:
stosw ;store both bytes to the dest
and ah,ah ;is the 2nd byte the
; terminating 0?
jnz CopyAndConvertLoop ;if not, repeat loop
jmp short Done ;if so, we're done
SaveLastAndDone:
stosb ;store the final 0 to the dest
Done:
pop di ;restore C's register vars
pop si
pop bp ;restore caller's stack frame
ret
_CopyUppercase endp
end
[LISTING FIVE]
; C near-callable subroutine, callable as:
; void CopyUppercase(char *DestPtr, char *SourcePtr);
;
; Copies one near string to another near string, converting all lower
; case letters to upper case before storing them. Strings must be
; zero-terminated. Uses extensive optimization for enhanced
; performance.
;
parms struc
dw ? ;pushed BP
dw ? ;return address
DestPtr dw ? ;destination string
SourcePtr dw ? ;source string
parms ends
;
.model small
.data
; Table of mappings to uppercase for all 256 ASCII characters.
UppercaseConversionTable label byte
ASCII_VALUE=0
rept 256
if (ASCII_VALUE lt 'a') or (ASCII_VALUE gt 'z')
db ASCII_VALUE ;non-lower-case characters
; map to themselves
else
db ASCII_VALUE and not 20h ;lower-case characters map
; to upper-case equivalents
endif
ASCII_VALUE=ASCII_VALUE+1
endm
;
.code
public _CopyUppercase
_CopyUppercase proc near
push bp
mov bp,sp ;set up stack frame
push si ;preserve C's register vars
push di
;
mov di,[bp+DestPtr] ;point DI to destination
mov si,[bp+SourcePtr] ;point SI to source
mov bx,offset UppercaseConversionTable
;point BX to lower-case to
; upper-case mapping table
; This loop processes up to 16 bytes from the source string at a time,
; branching only every 16 bytes or after the terminating 0 is copied.
CopyAndConvertLoop:
rept 15 ;for up to 15 bytes in a row...
lodsb ;get the next source byte
xlat ;make sure it's upper case
stosb ;save it to the destination
and al,al ;is this the terminating 0?
jz Done ;if so, then we're done
endm
lodsb ;get the next source byte
xlat ;make sure it's upper case
stosb ;save it to the destination
and al,al ;is this the terminating 0?
jnz CopyAndConvertLoop ;if not, repeat loop
Done:
pop di ;restore C's register vars
pop si
pop bp ;restore caller's stack frame
ret
_CopyUppercase endp
end