Как выйти из цикла в сборке

#assembly #x86

#сборка #x86

Вопрос:

У меня есть цикл с несколькими условиями, что означает, что по завершении цикла он продолжит проходить оставшийся сегмент цикла. Как я могу заставить программу пропустить оставшийся сегмент цикла, даже если ecx уже равен 0?

Комментарии:

1. Разве вы не можете просто jmp выйти из цикла?

Ответ №1:

Циклы и условия создаются с помощью МЕТОК, СРАВНЕНИЙ и ПЕРЕХОДОВ:

 xor ecx,ecx                ;ECX = 0
mov eax,8                  ;EAX = 8
mov ebx,4                  ;EBX = 4

START_LOOP:

sub eax,ebx                ;EAX = EAX - EBX
cmp eax,ecx                ;compare EAX and ECX
jne START_LOOP             ;if EAX != ECX, jump back and loop
                           ;When EAX = ECX, execution continues pas the jump
  

Вы можете выполнять цикл несколько раз, используя индекс цикла, который мы обычно вводим в ECX:

 xor ecx,ecx                ;ECX = 0
mov eax,2                  ;EAX = 2
mov ebx,2                  ;EBX = 2

START_LOOP:

add eax,ebx                ;EAX = EAX   EBX
inc ecx                    ;ECX = ECX   1
cmp ecx,5                  ;compare ECX and 5
jne START_LOOP             ;if ECX != 5 jump back and loop
                           ;When ECX == 5, execution continues pas the jump
  

Наконец, вы можете использовать условия внутри цикла, используя разные метки:

 xor ecx,ecx                ;ECX = 0
mov eax,2                  ;EAX = 2
xor ebx,ebx                ;EBX = 0

START_LOOP:

cmp eax,ebx               ;compare EAX and EBX
jle CONTINUE              ;if EAX <= EBX jump to the CONTINUE label
inc ebx                   ;else EBX = EBX   1
jmp START_LOOP            ;JUMP back to the start (until EBX>=EAX)
                          ;You'll never get past this jump until the condition in reached

CONTINUE:
add eax,ebx                ;EAX = EAX   EBX
inc ecx                    ;ECX = ECX   1
cmp ecx,5                  ;compare ECX and 5
jne START_LOOP             ;if ECX != 5 jump back and loop
                           ;When ECX == 5, execution continues pas the jump
  

Комментарии:

1. Стоит отметить, что если конечное условие равно нулю, вы можете выполнить цикл с чем-то вроде dec ecx / jnz TOP_OF_LOOP . Кроме того, если телу цикла может потребоваться выполнить нулевое время, лучше поставить флажок и перепрыгнуть через него вне цикла и по-прежнему использовать цикл с cmp/jcc внизу. (Ваш CONTINUE цикл неэффективен: в нем есть не принятая условная ветвь и условная ветвь, которые должны выполняться на каждой итерации.)

Ответ №2:

Вам придется пропустить их. Это единственное управление потоком, которое вы получаете. Попробуйте эмулировать структуру, которую вы бы использовали на языке более высокого уровня, чтобы избежать создания спагетти-кода.

Комментарии:

1. но, к чему мне перейти. Должен ли я создать какую-то метку?

2. Да, вы создаете метку после цикла и переходите к ней.