Поиск ошибок. Почему код неправильно работает, когда впереди стоят 1 или 2 пробела? - Assembler

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

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

Задание: удалить пробелы в строке.
Листинг программы
  1. void func(char *from, int n)
  2. {
  3. __asm
  4. {
  5. mov edi, from
  6. mov esi, from
  7. mov ecx, n
  8. start:
  9. cmp ecx, 0
  10. je finish
  11. cmp [edi], ' '
  12. je yes
  13. jmp no
  14. yes:
  15. dec ecx
  16. inc edi
  17. jmp start
  18. no:
  19. dec ecx
  20. mov eax , [edi]
  21. mov [esi] , eax
  22. inc esi
  23. inc edi
  24. jmp start
  25. finish:
  26. mov [esi], 0
  27. }
  28. }
  29. int main()
  30. {
  31. char str1[] = " abcd; ";
  32. func(str1, strlen(str1));
  33. cout << "|" << str1 << "|" << endl;
  34. system("pause");
  35. return 0;
  36. }

Решение задачи: «Поиск ошибок. Почему код неправильно работает, когда впереди стоят 1 или 2 пробела?»

textual
Листинг программы
  1. __asm {
  2.  
  3.        mov   esi,from       ; ESI/EDI - адрес строки
  4.        mov   edi,esi        ;
  5.        mov   ecx,n          ; длина строки
  6.        xor   ax,ax          ;
  7. cycle: lodsb                ; считать символ из ESI
  8.        cmp   al,' '         ; пробел?
  9.        jne   miss           ; нет - пропускаем
  10.        cmp   ax,'  '        ; да - тест с предыдущим
  11.        je    next           ; 2 пробела - пропускаем
  12. miss:  stosb                ; перезапись символа в ESI
  13. next:  xchg  ah,al          ; запомним текущий символ
  14.        loop  cycle          ;
  15.  
  16.        mov   al,0           ; вставляем маркер конца стоки
  17.        stosb                ;
  18.        }

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

В данном коде на языке Assembler выполняется поиск двух пробелов подряд в строке. Вот список действий, которые происходят в коде:

  1. mov esi, from — в ESI записывается адрес строки.
  2. mov edi, esi — в EDI записывается тот же адрес, что и в ESI.
  3. mov ecx, n — в ECX записывается длина строки.
  4. xor ax, ax — в AX регистрерах устанавливается ноль.
  5. lodsb — из памяти, адрес которой находится в ESI, считывается один байт (символ).
  6. cmp al, ' ' — проверяется, является ли этот символ пробелом.
  7. jne miss — если это не пробел, то происходит переход к следующей итерации цикла.
  8. cmp ax, ' ' — проверяется, является ли текущий символ и предыдущий два пробела.
  9. je next — если это так, то происходит переход к следующей итерации цикла.
  10. stosb — в память по адресу ESI записывается ноль (маркер конца строки).
  11. xchg ah, al — происходит обмен между AH и AL регистрами.
  12. loop cycle — происходит переход к началу цикла. Если в начале строки есть один или два пробела, код не будет работать правильно, потому что он ожидает, что первое, что он встретит, будет пробел. Если это не так, он пропустит первый символ и начнет искать два пробела с конца строки, что может привести к неправильной обработке строки.

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


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

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

14   голосов , оценка 4.286 из 5

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

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

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