(MASM) Удаление второй подстроки из первой и сохранение результата третью - Assembler

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

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

Здравствуйте! Три дня ломал голову над задачей и все-таки решил прибегнуть к вашей помощи. Даны три строки, S1, S2, S3. Удалить из S1 первое появление S2, остаточную строку записать в S3. Вывести все три строки. Вот мои безуспешные попытки
Листинг программы
  1. include Irvine32.inc
  2. Show macro string
  3. lea edx, string
  4. call WriteString
  5. call Crlf
  6. endm
  7. .data
  8. S1 db '3331234222222453322222222345',0
  9. S2 db '345',0
  10. S3 db sizeof S1 dup(0)
  11. len_S2 dd ?
  12. len_S1 dd ?
  13. s3_edi dd ?
  14. .code
  15. main proc
  16. Show S1
  17. ;lab S1, S2, S3
  18. cld
  19. mov edi, offset S2
  20. Invoke Str_length, edi
  21. mov len_S2, eax
  22. mov edi, offset S1
  23. Invoke Str_length, edi
  24. mov len_S1, eax
  25. lea edi, S3
  26. mov s3_edi, edi
  27. lea esi, S1
  28. lea edi, S2
  29. srch:
  30. lea edi, S2
  31. mov ecx, len_S2
  32. repe cmpsb
  33. jne mismatch
  34. jmp ext
  35. mismatch:
  36. pusha
  37. dec esi
  38. dec edi
  39. lodsb
  40. mov edi, s3_edi
  41. stosb
  42. popa
  43. inc s3_edi
  44. jmp srch
  45.  
  46. ext:
  47. Show S2
  48. Show S3
  49. exit
  50. main endp
  51. end main

Решение задачи: «(MASM) Удаление второй подстроки из первой и сохранение результата третью»

textual
Листинг программы
  1. org 100h
  2. jmp start
  3.  
  4. Str1   db  'ANBC-HD*G_HJV0125800 BKMC4 NX3451185ABCGEF00245',0
  5. len1   =   ($ - Str1)-1   ; длина строки (без нуль-терминала)
  6. Str2   db  '345',0
  7. len2   =   ($ - Str2)-1
  8. Str3   db  80 dup(0)
  9. crlf   db  13,10,'$'
  10.  
  11. start:
  12.    mov   bx,len1          ; BX = длина строки
  13.    xor   ax,ax            ; плавающая позиция
  14.    xor   dx,dx            ; это будет найденая позиция в строке
  15. @@:                       ;
  16.    mov   si,Str1          ; указатель на строку
  17.    mov   di,Str2          ;      ..и на под/строку
  18.    mov   cx,len2          ; длина под/строки
  19.    add   si,ax            ; добавляем плавающую позицию
  20.    mov   dx,si            ; запоминаем эту позицию
  21.    repe  cmpsb            ; сравниваем строки
  22.    jz    @f               ; переход, если есть вхождение
  23.    inc   ax               ; иначе: позиция поплыла вперёд
  24.    dec   bx               ;      ..а счётчик назад
  25.    jnz   @b               ; если не конец строки, то циклимся..
  26. ; ошибка поиска! ====================================================//
  27.    mov   al,7             ; бипер,
  28.    int   29h              ;
  29.    jmp   exit             ; ..и на выход!
  30.  
  31. ; Есть вхождение!
  32. ; На этом этапе SI установлен на первом/найденном символе, плюс длина под/строки.
  33. ; DX указывает на первый/найденный символ.
  34. @@:                       ;
  35.    mov   di,dx            ; вставляем по-адресу DX,
  36.    xor   al,al            ;   ..нуль-терминал (отрезали хвост).
  37.    stosb                  ;
  38.  
  39.    lea   cx,[Str1+len1]   ; вычисляем длину хвоста
  40.    sub   cx,dx            ;
  41.    sub   cx,len2          ;   ..без под/строки
  42.    mov   di,Str3          ; DI приёмник, SI источник
  43.    rep   movsb            ; копируем СХ-байт из SI в DI
  44.  
  45.    mov   si,Str1          ; выводим на экран получившиеся строки
  46.    call  WriteString      ; эта функция выводит строку на консоль (по-байтно),
  47.    mov   si,Str2          ;     ..пока не встретится нуль-терминал.
  48.    call  WriteString      ;
  49.    mov   si,Str3          ;
  50.    call  WriteString      ;
  51.  
  52. exit:                     ;
  53.    xor   ax,ax            ;
  54.    int   16h              ;
  55.    int   20h              ; на выход!
  56.  
  57. ;ннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннннн
  58. WriteString:              ;
  59.    mov   dx,crlf          ; курсор на новую строку
  60.    mov   ah,9             ;
  61.    int   21h              ;
  62. @@:                       ;
  63.    lodsb                  ; читаем байт из SI
  64.    or    al,al            ; нуль-терминал?
  65.    jz    @f               ;
  66.    int   29h              ; нет - печатаем символ.
  67.    jmp   @b               ;
  68. @@:                       ;
  69. ret                       ;

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

Код на языке Assembler выполняет удаление второй подстроки из первой и сохранение результата третьей. Список действий:

  1. Переменная len1 содержит длину строки Str1 (включая нуль-терминал), вычисленную как разность между Str1 и нуль-терминалом.
  2. Переменная len2 содержит длину подстроки Str2, вычисленную как разность между Str2 и нуль-терминалом.
  3. Переменная Str3 содержит результат, который будет отправлен на консоль.
  4. В цикле сравниваются символы строки Str1 и подстроки Str2. Если символы совпадают, то увеличивается счётчик совпадений в регистре bx.
  5. Если счётчик совпадений равен нулю, то регистры si и di инкрементируются на длину подстроки, и цикл продолжается.
  6. Если счётчик совпадений не равен нулю, то увеличивается регистр ax, который является плавающей позицией в строке.
  7. Делается переход на начало цикла, чтобы продолжить поиск совпадений.
  8. Если счётчик совпадений равен нулю, то делается переход на выход из программы.
  9. Если счётчик совпадений не равен нулю, то происходит копирование символов из строки Str1 в строку Str3.
  10. Выводится на консоль строка Str3.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

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

13   голосов , оценка 4.077 из 5

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

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

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