Инструкция цикла loop и jrcxz

Последнее обновление: 17.10.2023

Инструкция loop позволяют сократить определение цикла. Она уменьшает на 1 число в регистре RCX и переходит к определенной метке, если RCX не равен нулю. Пример использования на Linux:

global _start

section .text
_start:
    mov rcx, 5      ; регистр-счетчик
    mov rdi, 0
mainloop:           ; цикл
    add rdi, 2      ; некоторые действия цикла
    loop mainloop   ; уменьшаем значение в rcx на 1, переходим к метке mainloop, если rcx не содержит 0

    mov rax, 60
    syscall 

Здесь вначале инициализируем регистр-счетчик число 5. То есть цикл сделает 5 проходов. Цикл проектируется на метку mainloop. В цикле для теста увеличивает значение в регистре RDI на 2 и с помощью loopq mainloop уменьшаем значение в RCX на 1. И если в RCX НЕ число 0, возвращаемся к метке mainloop.

Аналогичный пример на Windows:

global _start

section .text
_start:
    mov rcx, 5      ; регистр-счетчик
    mov rax, 0
mainloop:           ; цикл
    add rax, 2      ; некоторые действия цикла
    loop mainloop   ; уменьшаем значение в rcx на 1, переходим к метке mainloop, если rcx не содержит 0
    ret

Инструкция loop имеет два дополнительных варианта: loope и loopne. loope продолжает цикл, если установлен флаг нуля. Инструкция loopne, наоборот, повторяет цикл, если флаг нуля не установлен. Например, применение инструкции loopne:

global _start

section .text
_start:
    mov rcx, 6      ; регистр-счетчик
    mov rdi, 0
mainloop:           ; цикл
    add rdi, 2      ; некоторые действия цикла
    loopne mainloop   ; уменьшаем значение в rcx на 1 и переходим к метке mainloop, если rcx не содержит 0

    mov rax, 60
    syscall 

В принципе тут все то же самое: loopne уменьшает значение в RCX на 1 и проверяет флаг нуля. Если флаг нуля не установлен, программа переходит обратно к метке mainloop.

jrcxz

Выполнение цикла часто зависит от некоторого счетчика - если счетчик равен определенному значению (чаще 0), то выполнение цикла прекращается. Традиционно в качестве подобного регистра-счетчика используется регистр RCX. Так, инструкция loop из начала статьи проверяет данный регистр. И для упрощения проверки условия архитектура Intel x86-64 также предоставляет инструкцию jrcxz - она проверяет значение RCX, и если оно рано 0, то переходит к определенной метке.

global _start
 
section .text
_start:
    mov rcx, 5      ; регистр-счетчик
    mov rdi, 1
mainloop:           ; цикл
    jrcxz exit      ; если rcx = 0, то переход к метке exit
    add rdi, 2      ; некоторые действия цикла
    loop mainloop  ; уменьшаем значение в rcx на 1, переходим к метке mainloop, если rcx не содержит 0

exit:
    mov rax, 60
    syscall

Здесь в цикле мы сразу проверяем, не равен ли регистр RCX нулю:

jrcxz exit

Если rcx=0, то переходим к метке exit. Подобная инструкция позволяет нам сразу вначале цикла проверить условие и не выполнять цикл, если условие (rcx не равен нулю) неверно.

Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850