home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / magazine / drdobbs / 1990 / 03 / abrash.lst next >
File List  |  1990-02-13  |  9KB  |  254 lines

  1. ASSEMBLY LANGUAGE LIVES!
  2. by Michael Abrash
  3.  
  4. [LISTING ONE]
  5.  
  6. /* Sample program to copy one far string to another far string,
  7.  * converting lower case letters to upper case letters in the process. */
  8.  
  9. #include <ctype.h>
  10.  
  11. char Source[] = "AbCdEfGhIjKlMnOpQrStUvWxYz0123456789!";
  12. char Dest[100];
  13.  
  14. /*
  15.  * Copies one far string to another far string, converting all lower
  16.  * case letters to upper case before storing them.
  17.  */
  18. void CopyUppercase(char far *DestPtr, char far *SourcePtr) {
  19.    char UpperSourceTemp;
  20.  
  21.    do {
  22.       /* Using UpperSourceTemp avoids a second load of the far pointer
  23.          SourcePtr as the toupper macro is expanded */
  24.       UpperSourceTemp = *SourcePtr++;
  25.       *DestPtr++ = toupper(UpperSourceTemp);
  26.    } while (UpperSourceTemp);
  27. }
  28.  
  29. main() {
  30.    CopyUppercase((char far *)Dest,(char far *)Source);
  31. }
  32.  
  33.  
  34.  
  35. [LISTING TWO
  36.  
  37. ; C near-callable subroutine, callable as:
  38. ;       void CopyUppercase(char far *DestPtr, char far *SourcePtr);
  39. ;
  40. ; Copies one far string to another far string, converting all lower
  41. ; case letters to upper case before storing them. Strings must be
  42. ; zero-terminated.
  43. ;
  44. parms   struc
  45.         dw      ?       ;pushed BP
  46.         dw      ?       ;return address
  47. DestPtr dd      ?       ;destination string
  48. SourcePtr dd    ?       ;source string
  49. parms   ends
  50. ;
  51.         .model small
  52.         .code
  53.         public _CopyUppercase
  54. _CopyUppercase  proc    near
  55.         push    bp
  56.         mov     bp,sp                   ;set up stack frame
  57.         push    si                      ;preserve C's register vars
  58.         push    di
  59. ;
  60.         push    ds                      ;we'll point DS to source
  61.                                         ; segment for the duration
  62.                                         ; of the loop
  63.         les     di,[bp+DestPtr]         ;point ES:DI to destination
  64.         lds     si,[bp+SourcePtr]       ;point DS:SI to source
  65. CopyAndConvertLoop:
  66.         lodsb                           ;get next source byte
  67.         cmp     al,'a'                  ;is it lower case?
  68.         jb      SaveUpper               ;no
  69.         cmp     al,'z'                  ;is it lower case?
  70.         ja      SaveUpper               ;no
  71.         and     al,not 20h              ;convert to upper case
  72. SaveUpper:
  73.         stosb                           ;store the byte to the dest
  74.         and     al,al                   ;is this the terminating 0?
  75.         jnz     CopyAndConvertLoop      ;if not, repeat loop
  76. ;
  77.         pop     ds                      ;restore caller's DS
  78. ;
  79.         pop     di                      ;restore C's register vars
  80.         pop     si
  81.         pop     bp                      ;restore caller's stack frame
  82.         ret
  83. _CopyUppercase  endp
  84.         end
  85.  
  86.  
  87. [LISTING THREE]
  88.  
  89. /* Sample program to copy one near string to another near string,
  90.  * converting lower case letters to upper case letters in the process. *
  91. /
  92. #include <ctype.h>
  93.  
  94. char Source[] = "AbCdEfGhIjKlMnOpQrStUvWxYz0123456789!";
  95. char Dest[100];
  96.  
  97. /*
  98.  * Copies one near string to another near string, converting all lower
  99.  * case letters to upper case before storing them.
  100.  */
  101. void CopyUppercase(char *DestPtr, char *SourcePtr) {
  102.    char UpperSourceTemp;
  103.  
  104.    do {
  105.       /* Using UpperSourceTemp allows slightly better optimization
  106.          than using *SourcePtr directly */
  107.       UpperSourceTemp = *SourcePtr++;
  108.       *DestPtr++ = toupper(UpperSourceTemp);
  109.    } while (UpperSourceTemp);
  110. }
  111.  
  112. main() {
  113.    CopyUppercase(Dest,Source);
  114. }
  115.  
  116.  
  117.  
  118. [LISTING FOUR]
  119.  
  120. ; C near-callable subroutine, callable as:
  121. ;       void CopyUppercase(char *DestPtr, char *SourcePtr);
  122. ;
  123. ; Copies one near string to another near string, converting all lower
  124. ; case letters to upper case before storing them. Strings must be
  125. ; zero-terminated.
  126. ;
  127. parms   struc
  128.         dw      ?       ;pushed BP
  129.         dw      ?       ;return address
  130. DestPtr dw      ?       ;destination string
  131. SourcePtr dw    ?       ;source string
  132. parms   ends
  133. ;
  134.         .model small
  135.         .code
  136.         public _CopyUppercase
  137. _CopyUppercase  proc    near
  138.         push    bp
  139.         mov     bp,sp                   ;set up stack frame
  140.         push    si                      ;preserve C's register vars
  141.         push    di
  142. ;
  143.         mov     di,[bp+DestPtr]         ;point DI to destination
  144.         mov     si,[bp+SourcePtr]       ;point SI to source
  145.         mov     cx,('a' shl 8) + 'z'    ;preload CH with lower end of
  146.                                         ; lower case range and CL with
  147.                                         ; upper end of that range
  148.         mov     bl,not 20h              ;preload BL with value used to
  149.                                         ; convert to upper case
  150. CopyAndConvertLoop:
  151.         lodsw                           ;get next two source bytes
  152.         cmp     al,ch                   ;is the 1st byte lower case?
  153.         jb      SaveUpper               ;no
  154.         cmp     al,cl                   ;is the 1st byte lower case?
  155.         ja      SaveUpper               ;no
  156.         and     al,bl                   ;convert 1st byte to upper case
  157. SaveUpper:
  158.         and     al,al                   ;is the 1st byte the
  159.                                         ; terminating 0?
  160.         jz      SaveLastAndDone         ;yes, save it & done
  161.         cmp     ah,ch                   ;is the 2nd byte lower case?
  162.         jb      SaveUpper2              ;no
  163.         cmp     ah,cl                   ;is the 2nd byte lower case?
  164.         ja      SaveUpper2              ;no
  165.         and     ah,bl                   ;convert 2nd byte to upper case
  166. SaveUpper2:
  167.         stosw                           ;store both bytes to the dest
  168.         and     ah,ah                   ;is the 2nd byte the
  169.                                         ; terminating 0?
  170.         jnz     CopyAndConvertLoop      ;if not, repeat loop
  171.         jmp     short Done              ;if so, we're done
  172. SaveLastAndDone:
  173.         stosb                           ;store the final 0 to the dest
  174. Done:
  175.         pop     di                      ;restore C's register vars
  176.         pop     si
  177.         pop     bp                      ;restore caller's stack frame
  178.         ret
  179. _CopyUppercase  endp
  180.         end
  181.  
  182.  
  183. [LISTING FIVE]
  184.  
  185. ; C near-callable subroutine, callable as:
  186. ;       void CopyUppercase(char *DestPtr, char *SourcePtr);
  187. ;
  188. ; Copies one near string to another near string, converting all lower
  189. ; case letters to upper case before storing them. Strings must be
  190. ; zero-terminated. Uses extensive optimization for enhanced
  191. ; performance.
  192. ;
  193. parms   struc
  194.         dw      ?       ;pushed BP
  195.         dw      ?       ;return address
  196. DestPtr dw      ?       ;destination string
  197. SourcePtr dw    ?       ;source string
  198. parms   ends
  199. ;
  200.         .model small
  201.         .data
  202. ; Table of mappings to uppercase for all 256 ASCII characters.
  203. UppercaseConversionTable        label   byte
  204. ASCII_VALUE=0
  205.         rept    256
  206. if (ASCII_VALUE lt 'a') or (ASCII_VALUE gt 'z')
  207.         db      ASCII_VALUE             ;non-lower-case characters
  208.                                         ; map to themselves
  209. else
  210.         db      ASCII_VALUE and not 20h ;lower-case characters map
  211.                                         ; to upper-case equivalents
  212. endif
  213. ASCII_VALUE=ASCII_VALUE+1
  214.         endm
  215. ;
  216.         .code
  217.         public _CopyUppercase
  218. _CopyUppercase  proc    near
  219.         push    bp
  220.         mov     bp,sp                   ;set up stack frame
  221.         push    si                      ;preserve C's register vars
  222.         push    di
  223. ;
  224.         mov     di,[bp+DestPtr]         ;point DI to destination
  225.         mov     si,[bp+SourcePtr]       ;point SI to source
  226.         mov     bx,offset UppercaseConversionTable
  227.                                         ;point BX to lower-case to
  228.                                         ; upper-case mapping table
  229. ; This loop processes up to 16 bytes from the source string at a time,
  230. ; branching only every 16 bytes or after the terminating 0 is copied.
  231. CopyAndConvertLoop:
  232.         rept    15            ;for up to 15 bytes in a row...
  233.         lodsb                           ;get the next source byte
  234.         xlat                            ;make sure it's upper case
  235.         stosb                           ;save it to the destination
  236.         and     al,al                   ;is this the terminating 0?
  237.         jz      Done                    ;if so, then we're done
  238.         endm
  239.  
  240.         lodsb                           ;get the next source byte
  241.         xlat                            ;make sure it's upper case
  242.         stosb                           ;save it to the destination
  243.         and     al,al                   ;is this the terminating 0?
  244.         jnz     CopyAndConvertLoop      ;if not, repeat loop
  245. Done:
  246.         pop     di                      ;restore C's register vars
  247.         pop     si
  248.         pop     bp                      ;restore caller's stack frame
  249.         ret
  250. _CopyUppercase  endp
  251.         end
  252.  
  253.  
  254.