1.asm 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. ; Вариант 19
  2. ; Еникеев И.Р. 2084/1
  3. .286
  4. .model tiny
  5. .data
  6. org 100h
  7. start:
  8. cmp byte ptr [from], 0 ; Test input string to non-empty
  9. jnz $+5
  10. jmp no_string
  11. xor cx, cx ; Begin of work
  12. not cx
  13. mov di, offset from
  14. mov al, ' '
  15. repz scasb ; Skip all spaces at the beginning
  16. dec di
  17. mov real_ofs, di ; Save offset of first non-space character
  18. xor ax, ax
  19. xor cx, cx
  20. not cx
  21. repnz scasb ; Search for tailing zero
  22. dec di
  23. dec di ; di - points to last non-zero char
  24. not cx
  25. dec cx
  26. push cx ; Save full length of string
  27. std ; Change direction flag to backwards
  28. mov al, ' '
  29. xor cx, cx
  30. not cx
  31. repz scasb ; Search for non-space charecter at the end of string
  32. inc di
  33. inc di ; di points to next after last non-space
  34. mov byte ptr [di], 0 ; Discard tailing spaces
  35. not cx
  36. dec cx ; Get count of tailing spaces
  37. pop ax
  38. sub ax, cx ; Calculate length of trimmed string (without leading and tailing spaces)
  39. jg $+5 ; If length is positive - countinue work
  40. jmp no_string
  41. cld ; Restore normal direction flag
  42. mov cx, ax ; Set trimmed length
  43. mov di, real_ofs ; Set pointer to the beginng of string
  44. xor bx, bx ; bx holds non-space chars count
  45. xor dx, dx ; dx holds word count-1
  46. word_loop: ; loop for calculate word and non-space char count in sentence
  47. mov al, [di] ; get char from string
  48. test al, al ; test for EOS
  49. jz next_1 ; If so - we are reached end of string
  50. cmp al, ' ' ; Compare with space
  51. jz inloop1 ; if so - skip all following spaces and inc word count
  52. inc bx ; Increment letters count
  53. inc di ; advance pointer
  54. dec cx ; decrement residuary string length
  55. jnz word_loop ; if we got non-tested chars - continue loop
  56. jmp next_1 ; if not - end our loop
  57. inloop1: ; If we've found space in input string
  58. inc dx ; Increment word count
  59. inc cx ; Inc string's length for next line's right work
  60. repz scasb ; Skip all following spaces in input string
  61. dec di ; Adjust pointer to point to first non-space char
  62. jmp word_loop ; Countinue loop
  63. next_1: mov ax, need_len ; Get our required output string length
  64. sub ax, bx ; Decrease this length by total count of letters
  65. ; to get count of spaces, that we need to arrange
  66. ; between words
  67. cmp ax, dx ; if that count is less than spaces we've got to put
  68. ; betten words to save them separated then
  69. jl bad_len ; Show error message
  70. mov bx, dx ; bx will hold count of gaps between words
  71. test bx, bx ; if we've got only one word - so we don't need any gaps
  72. jz just_copy
  73. xor dx, dx ; clear dx for normal div's work
  74. div bx ; AX - holds count of spaces, bx - count of gaps, so
  75. mov toins, ax ; new ax - holds space count in each gap, and
  76. ; dx - remainder of division
  77. just_copy: ; Prepare of our main loop of creation of output string
  78. mov si, real_ofs ; Source - input string
  79. mov di, offset to ; Destination - memory to hold output string
  80. main_loop: ; Here comes the main loop
  81. mov al, [si] ; get character
  82. test al, al ; if we're reached end of string
  83. jz wr_out ; goto write output
  84. cmp al, ' ' ; if we got space -
  85. jz space ; work with this gap
  86. movsb ; else just copy character from input to output
  87. jmp main_loop ; continue loop
  88. space: ; if we've got space - skip all following in input
  89. ; and add needed space count in gap in output
  90. xor cx, cx
  91. not cx
  92. xchg si, di ; scas works with di - so we need to put si there
  93. repz scasb ; al - hold ' ' (by that reason we are here)
  94. dec di ; so we've skipped all following spaces in input
  95. xchg di, si ; return poiners at their normal state
  96. mov cx, toins ; put needed space count in output string
  97. rep stosb ; in al we're still got ' '
  98. test dx, dx ; if our remainder are zero
  99. jz main_loop ; - continue loop
  100. stosb ; else - put one more space in current gap
  101. dec dx ; and decrease remainder
  102. jmp main_loop ; and of course continue our loop
  103. wr_out: ; Now we're reached final touches to our prog
  104. xor ax, ax ; We're going to search for tailing null char
  105. ; (we could skip this line because the only way to get here
  106. ; is only from testing al to zero, so it DEFINITLY zero)
  107. mov di, offset to ; point to output string
  108. xor cx, cx ; Search for FFFF chars
  109. not cx ;
  110. repnz scasb ; Search tailing zero
  111. dec di ; And put
  112. mov al, '$' ; '$'
  113. stosb ; instead of it
  114. mov ah, 9 ; Use DOS's help
  115. mov dx, offset to ; to write output
  116. int 21h ; to user's eyes
  117. jmp norm_out ; output is OK!
  118. bad_len:
  119. mov ah, 9h
  120. mov dx, offset bad_len_str
  121. int 21h
  122. jmp short norm_out
  123. no_string:
  124. mov ah, 9h
  125. mov dx, offset no_input_str
  126. int 21h
  127. jmp short norm_out
  128. norm_out:
  129. mov ah, 4ch
  130. int 21h
  131. toins dw 0
  132. divis dw 0
  133. wordcnt dw 0
  134. need_len dw 30
  135. real_ofs dw 0
  136. dw 0 ; front border of string
  137. from db ' so hello my dear world ',0
  138. db 100-($-from) dup (0)
  139. to db 100 dup (0)
  140. bad_len_str db 'Input string length exceeds needed length$'
  141. no_input_str db 'No input string entred$'
  142. end start