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

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

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

Задание: удалить пробелы в строке.
void func(char *from, int n)
 {
     __asm
     {
         mov edi, from
         mov esi, from
         mov ecx, n
start:   
         cmp ecx, 0
         je finish
         cmp [edi], ' ' 
         je yes
         jmp no
yes:
         dec ecx
         inc edi
         jmp start 
no:
         dec ecx
         mov  eax  , [edi]
         mov [esi] , eax 
         inc esi 
         inc edi
         jmp start
finish: 
         mov [esi], 0
     }
 }
int main()
{
    char str1[] = " abcd;     ";
    func(str1, strlen(str1));
    cout << "|" << str1 << "|" << endl;
    system("pause");
    return 0;
}

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

textual
Листинг программы
__asm {
 
       mov   esi,from       ; ESI/EDI - адрес строки
       mov   edi,esi        ;
       mov   ecx,n          ; длина строки
       xor   ax,ax          ;
cycle: lodsb                ; считать символ из ESI
       cmp   al,' '         ; пробел?
       jne   miss           ; нет - пропускаем
       cmp   ax,'  '        ; да - тест с предыдущим
       je    next           ; 2 пробела - пропускаем
miss:  stosb                ; перезапись символа в ESI
next:  xchg  ah,al          ; запомним текущий символ
       loop  cycle          ;
 
       mov   al,0           ; вставляем маркер конца стоки
       stosb                ;
       }

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

В данном коде на языке 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
Похожие ответы