home *** CD-ROM | disk | FTP | other *** search
File List | 1990-02-13 | 8.9 KB | 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
-
-