Установка битов по условию. setc

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

Ряд инструкций позволяют установить однобайтовый операнд в 0 или 1 в зависимости от значений в регистре FLAGS. Основные из них:

  • setc: устанавливает биты, если флаг переноса CF=1

  • setnc: устанавливает биты, если флаг переноса CF=0

  • setz: устанавливает биты, если флаг нуля ZF=1

  • setnz: устанавливает биты, если флаг нуля ZF=0

  • sets: устанавливает биты, если флаг знака SF=1

  • setns: устанавливает биты, если флаг знака SF=0

  • seto: устанавливает биты, если флаг переполнения OF=1

  • setno: устанавливает биты, если флаг переполнения OF=0

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

Еще две дополнительные группы инструкций могут применяться после инструкции cmp. Они позволяют узнать, является ли один операнд меньше, равен или больше другого. Одна группа предназначена для беззнакового сравнения, а вторая группа - для сравнения результатов со знаком.

Для сравнения беззнаковых чисел:

Инструкция

Условие

Описание

seta

CF = 0, ZF = 0

Если первый операнд больше второго

setnbe

CF = 0, ZF = 0

Если первый операнд не меньше и не равен второму (по сути больше второго - аналог seta)

setae

CF = 0

Если первый операнд больше или равен второму

setnb

CF = 0

Если первый операнд не меньше второго (аналог setae)

setb

CF = 1

Если первый операнд меньше второго

setnae

CF = 1

Если первый операнд не больше и не равен второму (меньше второго - аналог setb)

setbe

CF = 1 или ZF = 1

Если первый операнд меньше или равен второму

setna

CF = 1 или ZF = 1

Если первый операнд не больше второго (аналогичен setbe)

sete

ZF = 1

Если операнды равны (аналогичен setz)

setne

ZF = 0

Если операнды не равны (аналогичен setzn)

Для сравнения чисел со знаком:

Инструкция

Условие

Описание

setg

SF = OF и ZF = 0

Если первый операнд больше второго

setnle

SF = OF и ZF = 0

Если первый операнд не меньше и не равен второму (по сути больше второго - аналог setп)

setge

SF = OF

Если первый операнд больше или равен второму

setnl

SF = OF

Если первый операнд не меньше второго (аналог setge)

setl

Флаги SF и OF не равны

Если первый операнд меньше второго

setnge

Флаги SF и OF не равны

Если первый операнд не больше и не равен второму (меньше второго - аналог setl)

setle

Флаги SF и OF не равны или ZF = 1

Если первый операнд меньше или равен второму

setng

Флаги SF и OF не равны или ZF = 1

Если первый операнд не больше второго (аналогичен setle)

sete

ZF = 1

Если операнды равны (аналогичен setz)

setne

ZF = 0

Если операнды не равны (аналогичен setzn)

Общий формат инструкций:

setxxxx операнд8

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

В ряде языков программирования высокого уровня есть логический тип данных (bool, boolean), который может содержать одно из двух значений - true или false, то есть истинно или ложь. С помощью подобного типа данных можно установить, что какое-то условие верно, истинно или не верно, ложно. И подобные иИнструкции setxxx позволяют преобразовывать результат сравнения в подобное логическое значение. Если условие верно, то устанавливаетя 1, если неверно - то 0. Например:

.code
main proc
    mov eax, 0
    mov ecx, 6
    mov edx, 6
    cmp ecx, edx
    sete al
    ret
main endp
end

Здесь сравниваем значения регистров ECX и EDX. Инструкция

sete al

Проверяет равенство операндов из инструкции CMP, а по сути проверяет флаг нуля ZF - если он равен 1, то в регистр AL помещается значение 1. Если флаг нуля равен 0, то в регистр AL помещается 0. В данном случае операнды равны, поэтому в AL будет 1.

В языках высокого уровня это было бы аналогично следующему выражению

bool al = ecx == edx:

Подобным образом можно устанавливать переменные. Переменная в этом случае должна представлять тип byte

.data
    bool byte ?
.code
main proc
    mov ecx, 6
    mov edx, 6
    cmp ecx, edx
    setne bool
    movzx eax, bool
    ret
main endp
end

Здесь проверяем на неравенство, поэтому переменная bool будет равна 1, если значение регистров ECX и EDX не равны.

Подобным образом можно сравнивать более сложные конструкции. Например, возьмем следующий код на си-подобном языке:

bool result = ((a <= b) && (d == e)):

Здесь одновременно должно быть a меньше или равно b и d равно e. В этом случае выражение будет истинным. Определим подобное сравнение на ассемблере:

.data
    bool byte ?
.code
main proc
    mov ecx, 6
    mov edx, 16
    cmp ecx, edx
    setle bl        ; ecx <= edx
    
    mov r8d, 5
    mov r9d, 5
    cmp r8d, r9d
    sete bh         ; r8d == r9d
    and bh, bl      ; ecx <= edx && r8d == r9d
    movzx eax, bh
    ret
main endp
end
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850