home *** CD-ROM | disk | FTP | other *** search
/ The Unsorted BBS Collection / thegreatunsorted.tar / thegreatunsorted / programming / asm_programming / REV.8 < prev    next >
Text File  |  1994-01-31  |  4KB  |  87 lines

  1. ;---------------
  2. ;   REV
  3. ;---------------
  4.  
  5. ; REV is a filter that reverses all lines of standard input, and sends
  6. ;   the reversed lines to standard output.
  7.  
  8. DATA SEGMENT
  9. OBUFF:              ; output buffer
  10.   DB 02000 DUP (?)
  11. OBUFF_LIM:          ; limit signalling we are near the end of the output buffer
  12.   DB 0100 DUP (?)
  13. DATA ENDS
  14.  
  15. REV:
  16.   MOV BP,OBUFF         ; initialize the output buffer to empty
  17.   CALL VERIFY_NO_ARGS  ; verify that there were no arugments in the command tail
  18.   CALL PROCESS_INPUT   ; reverse all the line of standard input
  19.   CALL FLUSH_OUTPUT    ; flush the output buffer
  20.   JMP GOOD_EXIT        ; success-- exit back to the operating system
  21.  
  22.  
  23. ; VERIFY_NO_ARGS insures that there are no command-tail arguments at the
  24. ;   PSP buffer DS:080.  If there are, we abort with USAGE_MSG.
  25.  
  26. VERIFY_NO_ARGS:
  27.   MOV SI,080           ; point to the PSP command-tail
  28.   LODSB                ; fetch the length byte
  29.   CBW                  ; extend length AL into AX
  30.   XCHG CX,AX           ; swap the command tail length into CX
  31.   JCXZ RET             ; good return if there is no tail whatsoever
  32. L1:                    ; loop here for each byte of the command tail
  33.   LODSB                ; fetch a command-tail byte
  34.   CMP AL,' '           ; it had better be a blank or a control character
  35.   IF A JMP USAGE_EXIT  ; error exit if command tail has non-blank contents
  36.   LOOP L1              ; loop for the next command-tail byte
  37.   RET
  38.  
  39. USAGE_MSG:
  40.   DB 'usage: rev <in >out',0D,0A
  41. USAGE_SIZE EQU $ - USAGE_MSG
  42.  
  43.  
  44. ; PROCESS_LINE reverses the line of CX bytes pointed to by SI (and beyond by
  45. ;   DI), and copies the reversed line to the output buffer.
  46.  
  47. PROCESS_LINE:
  48.   DEC DI               ; decrement beyond-pointer back to linefeed
  49.   CMP B[DI-1],0D       ; is there also a CR terminating this line?
  50.   IF E DEC DI          ; if yes then decrment back to the CR, also
  51.   CALL REV_STRING      ; reverse the characters of the line
  52.   MOV DI,BP            ; fetch the output buffer pointer
  53.   REP MOVSB            ; copy the reversed line to the output buffer
  54.   MOV BP,DI            ; store the updated output buffer pointer
  55.   CMP BP,OBUFF_LIM     ; is the output buffer almost full?
  56.   JB RET               ; return if not
  57. FLUSH_OUTPUT:
  58.   PUSH AX,BX,CX,DX     ; preserve registers across call
  59.   MOV DX,OBUFF         ; point to the start of the output buffer
  60.   MOV CX,BP            ; point CX beyond the bytes we have placed in buffer
  61.   SUB CX,DX            ; calculate the number of bytes in the buffer
  62.   MOV BP,DX            ; reset the output pointer back to the buffer start
  63.   MOV BX,1             ; file handle for standard output is 1
  64.   CALL MWRITE          ; write the buffered bytes to standard output
  65.   POP DX,CX,BX,AX      ; restore clobbered registers
  66.   RET
  67.  
  68.  
  69. ; REV_STRING reverses the string running from DS:SI through DS:DI-1.  We do so
  70. ;    by repeatedly exchanging the bytes pointed to by each pointer, then moving
  71. ;    the pointers in towards each other, until they meet.
  72.  
  73. REV_STRING:
  74.   CMP SI,DI
  75.   JE RET
  76.   PUSH SI,DI        ; save registers across call
  77. L1:                 ; loop here for each pair of bytes
  78.   LODSB             ; fetch the SI-pointed byte
  79.   DEC DI            ; decrement DI to the last byte of the remaining string
  80.   XCHG AL,[DI]      ; exchange the SI-pointed byte with the DI-pointed byte
  81.   MOV [SI-1],AL     ; store the DI-pointed byte in the SI-pointed spot
  82.   CMP SI,DI         ; have SI and DI come together yet?
  83.   JB L1             ; loop if not to swap two more end-bytes
  84.   POP DI,SI         ; restore clobbered registers
  85.   RET               ; NoCarry set for disassembler MEMDIS_n's benefit
  86. 
  87.