Сравнение с переходом. Инструкции CBZ, CBNZ, TBZ и TBNZ

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

CBZ и CBNZ

Если надо проверить регистр на 0 и в зависимости от результата проверки выполнить переход к некоторой метке, то проще использовать специальные инструкции CBZ и CBNZ

CBNZ Wt/Xt, label
CBZ Wt/Xt, label

В качестве первого операнда они принимают регистр (64- или 32-разрядный), который нажо проверить на 0, а в качестве второго операнда - метку. Инструкция CBZ проверяет регистр и, если он равен 0, то выполняет переход к метке. Аналогично инструкция CBNZ также проверяет регистр и, если он не равен 0, выполняет переход к метке.

То есть выражение

CBNZ Xn, label

Фактически будет эквивалентно двум инструкциям

CMP Xn, #0
B.NE label

А выражение

CBZ Xn, label

Эквивалентно инструкциям

CMP Xn, #0
B.EQ label

Пример применения:

.global _start

_start:
    mov x1, #0          // сравниваемое значение

    cbz x1, zero       // если  x1 == 0, переход к метке zero
    mov x0, #1          // если x1 != 0 , то x0 = 1
    b exit
zero:
    mov x0, #2         // если x1 == 0, то x0 = 2
exit:
    mov x8, #93         // номер функции Linux для выхода из программы - 93
    svc 0               // вызываем функцию и выходим из программы

TBZ и TBNZ

Инструкции TBZ (Test bit and Branch if Zero) и TBNZ (Test bit and Branch if nonzero) проверяют установку бит непосредственного операнда в регистре и в зависимости от результата выполняют переход:

TBZ Wt/Xt, #imm, label
TBNZ Wt/Xt, #imm, label

TBZ проверяет установку бит #imm в регистре Wt/Xt, и если результатом проверки является 0, переходит к метке label. TBNZ, наоборот, переходит к метке label, если результат ненулевой. Пример применения:

// METANIT.COM. Пример программы с циклом типа do..while
.global _start
 
_start: 
    mov x1, #0b1011     // X1 = 11

    tbz x1, #0b0011, zero    // TST X1, #3 
    mov x0, #2          // если в Х1 есть число 0b0011
    b exit
zero:                 // собственно действия цикла while
    mov x0, #1          // если в Х1 нет числа 0b0011
exit:
    mov x8, #93         // номер функции Linux для выхода из программы - 93
    svc 0               // вызываем функцию и выходим из программы

Здесь проверяем наличие в регистре Х1 установленных битов числа 3 или 0b0011. То есть в Х1 должны быть установлены биты 0 и 1:

tbz x1, #0b0011, zero

Если эти биты НЕ установлены (то есть результат операции x1 AND #0b0011 равен 0), то переходим к метке zero.

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