| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241 |
- ; ‚ ਠâ 19
- ; ‚¥àá¨ï 2. „ ë¥ ¨§ ä ©« 2.txt
- ; …¨ª¥¥¢ ˆ.�. 2084/1
- .286
- cseg segment byte public 'CODE'
- assume cs:cseg, ds:dseg, es:dseg
- start:
- mov ax, seg dseg
- mov es, ax
- mov ds, ax
- ;------------------------------
- mov ax, 3d00h
- mov dx, offset fname
- int 21h
- jnc $+5
- jmp no_file
- push ax
- mov bp, 1 ; BP will hold ifWORK
- line_loop:
- pop bx
- mov cx, 1
- mov dx, offset from
- char_loop:
- mov ah, 3fh
- int 21h
- mov si, dx
- test ax, ax
- jz eof
- cmp byte ptr ds:[si], 0ah
- je eol
- inc dx
- jmp char_loop
- eol: mov byte ptr ds:[si-1], 0
- push bx
- jmp work
- eof: mov byte ptr ds:[si], 0
- xor bp, bp
- mov ah, 3eh
- int 21h
- work:
- cmp byte ptr [from], 0 ; Test input string to non-empty
- jnz $+5
- jmp no_string
- mov di, offset to
- add di, [need_len]
- mov [max_len], di
-
- xor cx, cx ; Begin of work
- not cx
- mov di, offset from
- mov al, ' '
- repz scasb ; Skip all spaces at the beginning
- dec di
- mov real_ofs, di ; Save offset of first non-space character
- xor ax, ax
- xor cx, cx
- not cx
- repnz scasb ; Search for tailing zero
- dec di
- dec di ; di - points to last non-zero char
- not cx
- dec cx
- push cx ; Save full length of string
- std ; Change direction flag to backwards
- mov al, ' '
- xor cx, cx
- not cx
- repz scasb ; Search for non-space charecter at the end of string
- inc di
- inc di ; di points to next after last non-space
- mov byte ptr [di], 0 ; Discard tailing spaces
- not cx
- dec cx ; Get count of tailing spaces
- pop ax
- sub ax, cx ; Calculate length of trimmed string (without leading and tailing spaces)
- jg $+5 ; If length is positive - countinue work
- jmp no_string
- cld ; Restore normal direction flag
- mov cx, ax ; Set trimmed length
- mov di, real_ofs ; Set pointer to the beginng of string
- xor bx, bx ; bx holds non-space chars count
- xor dx, dx ; dx holds word count-1
- word_loop: ; loop for calculate word and non-space char count in sentence
- mov al, [di] ; get char from string
- test al, al ; test for EOS
- jz next_1 ; If so - we are reached end of string
- cmp al, ' ' ; Compare with space
- jz inloop1 ; if so - skip all following spaces and inc word count
- inc bx ; Increment letters count
- inc di ; advance pointer
- dec cx ; decrement residuary string length
- jnz word_loop ; if we got non-tested chars - continue loop
- jmp next_1 ; if not - end our loop
- inloop1: ; If we've found space in input string
- inc dx ; Increment word count
- inc cx ; Inc string's length for next line's right work
- repz scasb ; Skip all following spaces in input string
- dec di ; Adjust pointer to point to first non-space char
- jmp word_loop ; Countinue loop
-
- next_1: mov ax, need_len ; Get our required output string length
- sub ax, bx ; Decrease this length by total count of letters
- ; to get count of spaces, that we need to arrange
- ; between words
- cmp ax, dx ; if that count is less than spaces we've got to put
- ; betten words to save them separated then
- jge need_spaces ; Show error message
- mov toins, 1 ; We'll have to crop input string, so leave we'll
- ; only one space as gaps
- xor dx, dx ; And don't need for additional spaces
- jmp just_copy
- need_spaces:
- mov bx, dx ; bx will hold count of gaps between words
- test bx, bx ; if we've got only one word - so we don't need any gaps
- jz just_copy
- xor dx, dx ; clear dx for normal div's work
- div bx ; AX - holds count of spaces, bx - count of gaps, so
- mov toins, ax ; new ax - holds space count in each gap, and
- ; dx - remainder of division
- just_copy: ; Prepare of our main loop of creation of output string
- mov si, real_ofs ; Source - input string
- mov di, offset to ; Destination - memory to hold output string
-
- main_loop: ; Here comes the main loop
- cmp di, [max_len]
- jl $+4
- jmp wr_out
- mov al, [si] ; get character
- test al, al ; if we're reached end of string
- jz wr_out ; goto write output
- cmp al, ' ' ; if we got space -
- jz space ; work with this gap
- movsb ; else just copy character from input to output
- jmp main_loop ; continue loop
- space: ; if we've got space - skip all following in input
- ; and add needed space count in gap in output
- xor cx, cx
- not cx
- xchg si, di ; scas works with di - so we need to put si there
- repz scasb ; al - hold ' ' (by that reason we are here)
- dec di ; so we've skipped all following spaces in input
- xchg di, si ; return poiners at their normal state
- mov cx, toins ; put needed space count in output string
- rep stosb ; in al we're still got ' '
- test dx, dx ; if our remainder are zero
- jz main_loop ; - continue loop
- stosb ; else - put one more space in current gap
- dec dx ; and decrease remainder
- jmp main_loop ; and of course continue our loop
-
- wr_out: ; Now we're reached final touches to our prog
- mov byte ptr [di], 0
- xor ax, ax ; We're going to search for tailing null char
- ; (we could skip this line because the only way to get here
- ; is only from testing al to zero, so it DEFINITLY zero)
- mov di, offset to ; point to output string
- xor cx, cx ; Search for FFFF chars
- not cx ;
- repnz scasb ; Search tailing zero
- dec di ; And put
- mov al, '$' ; '$'
- stosb ; instead of it
- mov ah, 9 ; Use DOS's help
- mov dx, offset to ; to write output
- int 21h ; to user's eyes
- mov dx, offset newline
- int 21h
- outta:
- test bp, bp
- jz norm_out
- jmp line_loop; output is OK!
- bad_len:
- jmp short norm_out
- no_string:
- mov ah, 09h
- mov dx, offset newline
- int 21h
- jmp short outta
- no_file:
- mov ah, 09h
- mov dx, offset no_file_str
- int 21h
- jmp norm_out
- err_read:
- mov ah, 09h
- mov dx, offset err_read_str
- int 21h
- jmp norm_out
- norm_out:
- mov ah, 4ch
- int 21h
- ends
- dseg segment para public 'DATA'
- fname db '2.txt',0
- toins dw 0
- divis dw 0
- wordcnt dw 0
- need_len dw 100
- real_ofs dw 0
- max_len dw 0
- newline db 0dh, 0ah, '$'
- no_file_str db 'Couldn''t open file 2.txt$'
- err_read_str db 'Error while reading 2.txt$'
- dw 0 ; front border of string
- from db 200 dup (?)
- to db 100 dup (?)
- ends
- sseg segment stack
- db 200 dup (?)
- ends
- end start
|