Перепечатать заданный текст, удалив из него символы "b", непосредственно перед которыми следует цифра - Assembler

Узнай цену своей работы

Формулировка задачи:

УЖЕ есть код , но он почему то у меня зациклился , помогите исправить , или предложите свой вариант , заранее спасибо

Решение задачи: «Перепечатать заданный текст, удалив из него символы "b", непосредственно перед которыми следует цифра»

textual
Листинг программы
  1. ; Задание : Перепечатать заданный текст, удалив из него символы "b", непосредственно перед которыми следует цифра.
  2. ;
  3. .MODEL  SMALL
  4. .STACK  100H
  5. .DATA
  6. TEXT    DB  'ack45ab4bc54',0
  7. .CODE
  8. MAIN    PROC    NEAR
  9.     MOV AX, @DATA
  10.     MOV DS, AX
  11.     CLD
  12.     MOV si, OFFSET TEXT
  13.  
  14.     mov bl, 'b'
  15.     mov dl, 0   ; 1 - если ранее была выведена цифра, 0 - если цифра не выводилась ранее
  16.  
  17. @@loop:
  18.     lodsb
  19.     test    al, al      ; достигнут ли конец строки?
  20.     jz  @@end       ; если да - прекратить цикл
  21.     cmp al, bl      ; символ "b"?
  22.     jne @@disp      ; если нет, то перейти к выводу символа
  23.     test    dl, dl      ; был ли предыдущий символ цифрой?
  24.     jne @@skip_disp ; если dl не равен нулю, значит ранее была выведена цифра
  25. @@disp:
  26.     call    DispAl
  27. @@skip_disp:
  28.     call    IsAlDigit   ; возвращает в al 1 если там был символ цифры и 0 в противном случае
  29.     mov dl, al
  30.     jmp @@loop
  31. @@end:
  32.     mov al, 0dh
  33.     call    DispAl
  34.     mov al, 0ah
  35.     call    DispAl
  36.  
  37.     MOV ax,4C00h
  38.     INT 21H
  39. MAIN    ENDP
  40. ;===================
  41. DispAl  PROC    NEAR
  42.     push    ax
  43.     push    dx 
  44.     mov ah, 2
  45.     mov dl, al
  46.     int 21h
  47.     pop dx
  48.     pop ax
  49.     ret
  50. DispAl  ENDP
  51. ;===================
  52. IsAlDigit   PROC    NEAR
  53. ; On Enter:
  54. ;   AL <- символ
  55. ; OnExit:
  56. ;   AL=1, если в AL ASCII цифра
  57. ;   AL=0, в противном случае
  58.     sub al, 30h
  59.     js  @@non_digit
  60.     sub al, 10
  61.     jns @@non_digit
  62.     mov al, 1
  63.     jmp @@exit
  64. @@non_digit:
  65.     xor al, al
  66. @@exit:
  67.     ret
  68. IsAlDigit   ENDP
  69. ;===================
  70.     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

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы