Перепечатать заданный текст, удалив из него символы "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

Объяснение кода листинга программы

  1. Объявление переменных:
    • TEXT: строковая переменная, содержащая исходный текст ack45ab4bc54
    • AX, DS, SI, BL, DL, AL, AH: регистровые переменные
  2. Инициализация регистров:
    • MOV AX, @DATA: копирование адреса сегмента данных в регистр AX
    • MOV DS, AX: перемещение значения из регистра AX в регистр DS
    • CLD: установка флага направления вперед
  3. Начало цикла:
    • MOV SI, OFFSET TEXT: перемещение адреса начала текста в регистр SI
    • MOV BL, 'b': сохранение символа 'b' в регистр BL
    • MOV DL, 0: инициализация переменной DL в 0
  4. Цикл:
    • 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: переход к началу цикла
  5. Окончание цикла:
    • MOV AL, 0DH: сохранение символа возврата каретки ('\r') в регистр AL
    • CALL DispAl: вызов процедуры DispAl для вывода символа
    • MOV AL, 0AH: сохранение символа новой строки ('\n') в регистр AL
    • CALL DispAl: вызов процедуры DispAl для вывода символа
  6. Завершение программы:
    • MOV AX, 4C00H: загрузка значения для завершения программы в регистр AX
    • INT 21H: вызов функции операционной системы для завершения программы
  7. Процедура DispAl:
    • Сохранение значений регистров AH, DX в стеке
    • MOV AH, 2: загрузка значения для вывода символа в регистр AH
    • MOV DL, AL: копирование значения из регистра AL в регистр DL
    • INT 21H: вызов функции операционной системы для вывода символа
    • Восстановление значений регистров DX, AX из стека
    • RET: возврат из процедуры
  8. Процедура 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: возврат из процедуры
  9. Конец программы.

Оцени полезность:

9   голосов , оценка 3.778 из 5
Похожие ответы