Нужна помощь (Microsoft Macro Assembler 6.11).
Постановка: с клавиатуры вводится непустой символьный текст, оканчивающийся точкой. Требуется:
-ввести текст в память ЭВМ
-проверить, сколько в тексте латинских букв
-если не меньше 3, то заменить все прописные латинские буквы на противоположные им по алфавиту (т.е. A заменяется на Z, B на Y, C на X и т.д.)
-иначе оставить в тексте те только символы (не обязательно буквы), которые встречаются в тексте 1 раз
-распечатать результат на экран
Преобр-ния текста должны быть оформлены в виде процедур, получ. парам. через стек, для ввода-вывода нужно использовать операции Inch, Outch и Outstr, для завершения работы - Finish.
Вывод текста, проверка условия и первое преобр-ние уже реализованы. Процедура второго преобр-ния работает неверно - при запуске программа висит и вылетает в форточки.
Вот уже написанный код:
Код:
include io.asm
stack segment stack
dd 128 dup (?)
stack ends
data segment
text db 100 dup (?)
endtext db 100 dup (?)
N dw ?
mes1 db 'Исходный текст:','$'
mes2 db 'Преобразованный текст:','$'
mes3 db 'Условие выполнено','$'
mes4 db 'Условие не выполнено','$'
data ends
code segment 'code'
assume ss:stack, ds:data, cs:code
outtxt proc near
;процедура вывода текста на экран до первой встретившейся точки
;параметры: адрес начала текста - через BX
;рез.-т: текст вывден на экран дисплея
;использует и сохраняет регистры: BX, Si, AX
push si
push ax
mov si,0
cyc1: mov al, [bx][si]
cmp al,'.'
je endcyc1
outch al
inc si
jmp cyc1
endcyc1:
pop ax
pop si
ret
outtxt endp
cond1 proc near
;процедура, реализующая первое преобразование текста
;параметры: адрес начала исх. текста, и его длина, адрес конечного текста - через стек
;использует и сохраняет регистры: AX, BX, CX, SI
push bp
mov bp,sp
;сохранение регистров
push ax
push bx
push cx
push si
mov cx,[bp+6]
mov bx,[bp+8]
xor si,si
cyc2:
mov al,[bx][si]
cmp al,'A'
jb nxtcyc2
cmp al,'Z'
ja nxtcyc2
sub al,'A'
neg al
add al,'Z';в al - код нужной буквы
nxtcyc2:
push bx
mov bx,[bp+4]
mov [bx][si],al
pop bx
inc si
loop cyc2
mov al,'.'
mov bx,[bp+4]
mov 1[bx][si],al
;восстановление регистров
pop si
pop cx
pop bx
pop ax
pop bp
ret 2*3
cond1 endp
cond2 proc near
;процедура второго преобразования текста
;параметры: адрес начала исх. текста, и его длина, адрес конечного текста - через стек
;вспом. перем. : промежуточный текст
;использует и сохраняет регистры: AX, BX, CX, SI, DI
;ПРИМЕЧАНИЕ: задача решается в предположении, что в тексте могут быть только графически представимые символы, которые можно ввести с клавиатуры, и что в используемой кодировке код символа " " есть наименьший из кодов таких символов
push bp
mov bp,sp
;сохранение регистров
push ax
push bx
push cx
push si
push di
mov cx,[bp+6]
mov bx,[bp+8]
xor si,si
push cx
;сохр. копию исх. текста
cyc3:mov al,[bx][si]
mov cs:tmp[si],al
inc si
loop cyc3
xor si,si
pop cx
push cx
cyc4:mov al,[bx][si]
mov ah, al; копия тек. символа
push cx
dec cx
jcxz sk3
mov di,si
inc di
cyc5:cmp al,[bx][di]
jne dif
mov ah,' '-1;если попались символы, совп. с текущим - забиваем вместо них нечто извне диапазона отображаемых символов
mov [bx][di], ah
dif:inc di
loop cyc5
mov [bx][si],ah;если среди ост. символов не попалось совп. с текущим - ничего не изменится, в прот. случае заменяем тек. символ на неотображаемый
inc si
pop cx
loop cyc4
sk3:pop cx; в temp - преобр. текст с вкраплениями неотобр. символов
xor si,si
xor di,di
mov bx,[bp+4];*адрес исх. массива нет надобности более хранить в BX
cyc6:mov al,cs:tmp[si]
cmp al,' '-1
je unrdbl
mov [bx][di],al
inc di
unrdbl:inc si
loop cyc6
mov al,'.'
mov 1[bx][di],al;завершающая точка в кон. тексте
;восстановление регистров
pop di
pop si
pop cx
pop bx
pop ax
pop bp
ret 2*3
tmp db 100 dup (?)
cond2 endp
start:
mov ax,data
mov ds,ax
;ввод исх. текста
mov cx,100
mov bx,0
L:inch al
mov text[bx], al
cmp al,'.'
je stop
inc bx
loop L
stop:
mov cx, bx; в CX - длина текста без точки
mov N,cx
;вывод исходного текста
lea dx,mes1
outstr
newline
lea bx,text
call outtxt
newline
;проверка выполнения условия
xor dx,dx
xor bx,bx
L1: mov al,text[bx]
cmp al,'A'
jb lesser
cmp al,'Z'
ja lesser
inc dx
jmp next
lesser:
cmp al,'a'
jb next
cmp al,'z'
ja next
inc dx
next:
inc bx
loop L1
;в DX - кол.-во лат. букв в тексте
lea ax,text
push ax
push N
lea ax,endtext
push ax
cmp dx,3
jb cond_false
lea dx,mes3
outstr
newline
call cond1
jmp exit
cond_false:
lea dx,mes4
outstr
newline
call cond2
exit:lea dx,mes2
outstr
newline
lea bx,endtext
call outtxt
newline
inch al
finish
code ends
end start