home *** CD-ROM | disk | FTP | other *** search
/ The C Users' Group Library 1994 August / wc-cdrom-cusersgrouplibrary-1994-08.iso / listings / v_02_02 / 2n02035c < prev    next >
Text File  |  1990-06-25  |  5KB  |  134 lines

  1.  
  2.     COMMENT     @
  3.  
  4.         Character Case Conversion Tables:
  5.  
  6.             Illustrates the use of REPT block to initialize data
  7.             Accessible to C program by function call or indirection
  8.             
  9.             C Function Prototypes:
  10.             
  11.                 char *str2upper(char *dest, char *source);
  12.                 
  13.                 char *str2lower(char *dest, char *source);
  14.                 
  15.                 Note:
  16.                     To convert string in place, pass pointer to
  17.                     source in both parameters ( must be L Value )
  18.  
  19.             C program considers tables to be char arrays:
  20.             
  21.                 extern char up_case[256], low_case[256];
  22.                 
  23.             Indirection Examples:
  24.             
  25.                 unsigned c;
  26.                 char uch, lch;
  27.  
  28.                 c = 'l';
  29.                 uch = up_case[c];
  30.                 c = 'L';
  31.                 lch = low_case[c];
  32.  
  33.         Version 1.0  --  Small Memory Model
  34.         To assemble with Masm V. 5.0  --  masm /b60 /Ml chartab;
  35.             June 26, 1990
  36.             Michael Kelly  --  Author
  37.                 May be used freely if authorship is acknowledged
  38.         @
  39.  
  40. _DATA   SEGMENT WORD    PUBLIC  'DATA'
  41. _up_case    LABEL   BYTE
  42. temp_c      =   0
  43.             REPT    97              ;this part of table is unchanged
  44.             DB  temp_c
  45. temp_c      =   temp_c + 1
  46.             ENDM
  47.  
  48. temp_c      =   'A'                 ;temp_c == 'a' so reset to upper case
  49.             REPT    26
  50.             DB  temp_c            ;put 'A'-'Z' where 'a'-'z' would be
  51. temp_c      =   temp_c + 1
  52.             ENDM
  53.  
  54. temp_c      =   '{'                 ;return to normal position in Ascii set
  55.             REPT    256 - '{'       ;and complete the upper case table
  56.             DB  temp_c
  57. temp_c      =   temp_c + 1
  58.             ENDM
  59.  
  60. _low_case   LABEL   BYTE
  61. temp_c      =   0
  62.             REPT    65              ;first 65 chars unchanged
  63.             DB  temp_c
  64. temp_c      =   temp_c + 1
  65.             ENDM
  66.  
  67. temp_c      =   'a'                 ;temp_c == 'A' so reset to lower case
  68.             REPT    26
  69.             DB  temp_c              ;put 'a'-'z' where 'A'-'Z' would be
  70. temp_c      =   temp_c + 1
  71.             ENDM
  72.  
  73. temp_c      =   '['                 ;return to normal position in Ascii set
  74.             REPT    256 - '['       ;and complete the lower case table
  75.             DB  temp_c
  76. temp_c      =   temp_c + 1
  77.             ENDM
  78.  
  79.             PUBLIC  _up_case, _low_case     ;make accessible to C program
  80. _DATA       ENDS
  81.  
  82. STACK       SEGMENT STACK   'STACK'
  83. STACK       ENDS
  84.  
  85. DGROUP      GROUP   _DATA, STACK
  86.  
  87. _TEXT       SEGMENT WORD    PUBLIC  'CODE'
  88.             PUBLIC  _str2upper, _str2lower  ;make accessible to C program
  89.  
  90.             ASSUME  CS:_TEXT, DS:DGROUP, SS:DGROUP, ES:NOTHING
  91. _str2upper  PROC    NEAR
  92.             MOV     BX,OFFSET DGROUP: _up_case      ;point BX to base of table
  93.             JMP     SHORT set_stack                 ;jump to common code
  94. _str2upper  ENDP
  95.  
  96.     ;On Entry to either Procedure, DS is assumed to hold DGROUP segment
  97.  
  98. set_stack:  PUSH    BP
  99.             MOV     BP,SP       ;save stack frame and Turbo C registers
  100.             PUSH    SI
  101.             PUSH    DI
  102.             PUSHF               ;preserve direction flag, just to be safe
  103.             CLD                 ;clear direction flag - SI and DI increment
  104.             MOV     AX,DS       ;this is faster than PUSH DS:POP ES sequence
  105.             MOV     ES,AX
  106.             MOV     DI,[BP+4]
  107.             MOV     SI,[BP+6]
  108.             MOV     DX,DI           ;save *dest for C function return value
  109.  
  110.                         ;use EVEN directive to start loop on word boundary
  111.                         ;for instruction fetch speed on 8086+ processors
  112.             EVEN                    
  113. next_char:  LODSB                   ;AL = *source++
  114.             XLAT                    ;convert char with "Translate" instruction
  115.             STOSB                   ;*dest++ = AL
  116.             OR      AL,AL           
  117.             JNZ     next_char       ;loop until '\0' terminator processed
  118.  
  119.             MOV     AX,DX           ;return *dest in AX
  120.             POPF
  121.             POP     DI              ;restore flags and registers
  122.             POP     SI
  123.             POP     BP
  124.             RETN                    ;"near return" instruction
  125.  
  126. _str2lower  PROC    NEAR
  127.             MOV     BX,OFFSET DGROUP: _low_case     ;point BX to base of table
  128.             JMP     SHORT set_stack                 ;jump to common code
  129. _str2lower  ENDP
  130.  
  131. _TEXT       ENDS
  132.         END
  133.  
  134.