Перепечатать заданный текст, удалив из него символы "b", непосредственно перед которыми следует цифра - Assembler
Формулировка задачи:
УЖЕ есть код , но он почему то у меня зациклился , помогите исправить , или предложите свой вариант , заранее спасибо
Решение задачи: «Перепечатать заданный текст, удалив из него символы "b", непосредственно перед которыми следует цифра»
textual
Листинг программы
- ; Задание : Перепечатать заданный текст, удалив из него символы "b", непосредственно перед которыми следует цифра.
- ;
- .MODEL SMALL
- .STACK 100H
- .DATA
- TEXT DB 'ack45ab4bc54',0
- .CODE
- MAIN PROC NEAR
- MOV AX, @DATA
- MOV DS, AX
- CLD
- MOV si, OFFSET TEXT
- mov bl, 'b'
- mov dl, 0 ; 1 - если ранее была выведена цифра, 0 - если цифра не выводилась ранее
- @@loop:
- lodsb
- test al, al ; достигнут ли конец строки?
- jz @@end ; если да - прекратить цикл
- cmp al, bl ; символ "b"?
- jne @@disp ; если нет, то перейти к выводу символа
- test dl, dl ; был ли предыдущий символ цифрой?
- jne @@skip_disp ; если dl не равен нулю, значит ранее была выведена цифра
- @@disp:
- call DispAl
- @@skip_disp:
- call IsAlDigit ; возвращает в al 1 если там был символ цифры и 0 в противном случае
- mov dl, al
- jmp @@loop
- @@end:
- mov al, 0dh
- call DispAl
- mov al, 0ah
- call DispAl
- MOV ax,4C00h
- INT 21H
- MAIN ENDP
- ;===================
- DispAl PROC NEAR
- push ax
- push dx
- mov ah, 2
- mov dl, al
- int 21h
- pop dx
- pop ax
- ret
- DispAl ENDP
- ;===================
- IsAlDigit PROC NEAR
- ; On Enter:
- ; AL <- символ
- ; OnExit:
- ; AL=1, если в AL ASCII цифра
- ; AL=0, в противном случае
- sub al, 30h
- js @@non_digit
- sub al, 10
- jns @@non_digit
- mov al, 1
- jmp @@exit
- @@non_digit:
- xor al, al
- @@exit:
- ret
- IsAlDigit ENDP
- ;===================
- END MAIN
Объяснение кода листинга программы
- Объявление переменных:
- TEXT: строковая переменная, содержащая исходный текст
ack45ab4bc54
- AX, DS, SI, BL, DL, AL, AH: регистровые переменные
- TEXT: строковая переменная, содержащая исходный текст
- Инициализация регистров:
- MOV AX, @DATA: копирование адреса сегмента данных в регистр AX
- MOV DS, AX: перемещение значения из регистра AX в регистр DS
- CLD: установка флага направления вперед
- Начало цикла:
- MOV SI, OFFSET TEXT: перемещение адреса начала текста в регистр SI
- MOV BL, 'b': сохранение символа 'b' в регистр BL
- MOV DL, 0: инициализация переменной DL в 0
- Цикл:
- LODSB: загрузка байта из памяти по адресу, указанному в регистре SI, в регистр AL и автоматическое инкрементирование SI
- TEST AL, AL: проверка, достигнут ли конец текста
- JZ @@end: если достигнут конец текста, переход к метке @@end и прекращение цикла
- CMP AL, BL: сравнение текущего символа с символом 'b'
- JNE @@disp: если текущий символ не равен 'b', переход к метке @@disp для вывода символа
- TEST DL, DL: проверка, была ли ранее выведена цифра
- JNE @@skip_disp: если переменная DL не равна 0, то переход к метке @@skip_disp, для пропуска вывода символа
- CALL DispAl: вызов процедуры DispAl для вывода символа
- @@skip_disp: переход к следующей итерации цикла
- CALL IsAlDigit: вызов процедуры IsAlDigit для определения, является ли текущий символ цифрой, результат сохраняется в регистре AL
- MOV DL, AL: сохранение значения из регистра AL в переменную DL
- JMP @@loop: переход к началу цикла
- Окончание цикла:
- MOV AL, 0DH: сохранение символа возврата каретки ('\r') в регистр AL
- CALL DispAl: вызов процедуры DispAl для вывода символа
- MOV AL, 0AH: сохранение символа новой строки ('\n') в регистр AL
- CALL DispAl: вызов процедуры DispAl для вывода символа
- Завершение программы:
- MOV AX, 4C00H: загрузка значения для завершения программы в регистр AX
- INT 21H: вызов функции операционной системы для завершения программы
- Процедура DispAl:
- Сохранение значений регистров AH, DX в стеке
- MOV AH, 2: загрузка значения для вывода символа в регистр AH
- MOV DL, AL: копирование значения из регистра AL в регистр DL
- INT 21H: вызов функции операционной системы для вывода символа
- Восстановление значений регистров DX, AX из стека
- RET: возврат из процедуры
- Процедура IsAlDigit:
- SUB AL, 30H: вычитание значения 30h из AL для преобразования символа в число
- JS @@non_digit: если результат отрицательный (знаковый флаг установлен), переход к метке @@non_digit
- SUB AL, 10: вычитание значения 10 из AL
- JNS @@non_digit: если результат неотрицателен (знаковый флаг не установлен), переход к метке @@non_digit
- MOV AL, 1: запись значения 1 в регистр AL, если символ является цифрой
- JMP @@exit: переход к метке @@exit
- @@non_digit: запись значения 0 в регистр AL, если символ не является цифрой
- @@exit: возврат из процедуры
- Конец программы.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д