Перепечатать заданный текст, удалив из него символы "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: возврат из процедуры
- Конец программы.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д