| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172 |
- ; Вариант 19
- ; Еникеев И.Р. 2084/1
- .286
- .model tiny
- .data
- org 100h
- start:
- cmp byte ptr [from], 0 ; Test input string to non-empty
- jnz $+5
- jmp no_string
- 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
- jl bad_len ; Show error message
-
- 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
- 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
- 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
- jmp norm_out ; output is OK!
- bad_len:
- mov ah, 9h
- mov dx, offset bad_len_str
- int 21h
- jmp short norm_out
- no_string:
- mov ah, 9h
- mov dx, offset no_input_str
- int 21h
- jmp short norm_out
- norm_out:
- mov ah, 4ch
- int 21h
- toins dw 0
- divis dw 0
- wordcnt dw 0
- need_len dw 30
- real_ofs dw 0
- dw 0 ; front border of string
- from db ' so hello my dear world ',0
- db 100-($-from) dup (0)
- to db 100 dup (0)
- bad_len_str db 'Input string length exceeds needed length$'
- no_input_str db 'No input string entred$'
- end start
|