Skip to content

Логические операции в Assembler

Здравствуйте, уважаемые читатели. Сегодня мы поговорим об основных логических операциях в Assembler, и по традиции, разберем практический пример.

Простые логические операторы

Известные всем логические операторы и в Assembler выполняют практически такие же функции. Мы рассмотрим самые основные и наиболее используемые:

  • Логическое побитовое И
  • Логическое побитовое ИЛИ
  • Исключающее побитовое ИЛИ
  • Логическое побитовое И

    В Assembler этот оператор сравнивает два регистра по одному биту. Он обозначается как and, и вот пример синтаксиса:
    ;пример логического И в Assembler
    mov bx, 01101001b
    mov bl, 01000111b
    and bx, bl

    Очевидно, что результатом этой операции будет 01000001, но возникает один вопрос: куда записывается результат выполнения оператора?

    Так вот, результат записывается в регистр, который стоит первым после оператора and, в нашем случае — это регистр bx, то есть теперь его значение поменялось на 01000001.

    Логическая инструкция test

    Во многих случаях нам бы не хотелось, чтобы число переписывалось и теряло своего первоначального значения. Именно для этого предусмотрели логическую инструкцию test. Она как и and производит побитовое умножение, но не записывает результат в какой либо регистр, а всего лишь поднимает флаги для каждого бита, то есть она имитирует выполнение инструкции and. И для лучшего восприятия мы рассмотрим пример на проверку четности числа с помощью логических операций в Assembler:

    .386
    .model flat,stdcall
    option casemap:none
    include ..\INCLUDE\kernel32.inc 
    include ..\INCLUDE\user32.inc 
    includelib ..\LIB\kernel32.lib 
    includelib ..\LIB\user32.lib 
    
    .data
    yes db "Chetnoe"
    no db "Ne chetnoe"
    stdout dd ?         
    cWritten dd ?
    
    .code
    start:
    invoke GetStdHandle, -11 ; дескриптор вывода
    mov stdout,eax           ; по умолчанию помещается в eax
    mov ah, 23
    test ah, 00000001b  ; сравниваем последний бит числа
    jz evn  
    invoke WriteConsoleA, stdout, ADDR no, sizeof no, ADDR cWritten, 0
    jmp exit
    evn:
    invoke WriteConsoleA, stdout, ADDR yes, sizeof yes, ADDR cWritten, 0
    exit:
    invoke ExitProcess,0  
    end start
    

    Число, которое мы проверяем на четность, помещаем в регистр ah, затем сравниваем последний бит числа с единицей, и если вернется единица, то число нечетное, а если ноль — четное, что соответственно выводится на экран. Напомню, что команда jz отвечает за условный переход на метку (метка evn), а команда jmp — за безусловный переход.

    Логическое побитовое ИЛИ

    В Assembler логическое побитовое ИЛИ обозначается or, и синтаксис идентичен синтаксису команды and, по своей сути представляет побитовое сложение.
    ;пример логического ИЛИ в Assembler
    mov bx, 01101001b
    mov bl, 01000111b
    or bx, bl

    Выполнение этой инструкции вернет 01101111 и поместит это двоичное число в регистр bx.

    Логическое исключающее ИЛИ

    Также помимо логического ИЛИ, часто используют исключающее ИЛИ в Assembler. Оно обозначается командой xor и выделяет различия в регистрах, то есть, если в одном бите содержится 1, а в другом 0, то xor вернет 1, если же в битах содержатся одинаковые значения, то xor вернет 0.

    Разберем на примере, за основу возьмем предыдущий пример проверки на четность:

    .386
    .model flat,stdcall
    option casemap:none
    include ..\INCLUDE\kernel32.inc 
    include ..\INCLUDE\user32.inc 
    includelib ..\LIB\kernel32.lib 
    includelib ..\LIB\user32.lib 
    
    .data
    yes db "Chetnoe"
    no db "Ne chetnoe"
    stdout dd ?         
    cWritten dd ?
    
    .code
    start:
    invoke GetStdHandle, -11 ; дескриптор вывода
    mov stdout,eax           ; по умолчанию помещается в eax
    xor ah, ah               ; обнуление регистра ah
    xor al, al               
    or ah, 21                ; помещаем в регистр число 21
    or al, 20
    xor ah, al
    xor al, ah
    xor ah, al               ; конструкция для смены значений регистров
    test ah, 00000001b  
    jz evn  
    invoke WriteConsoleA, stdout, ADDR no, sizeof no, ADDR cWritten, 0
    jmp exit
    evn:
    invoke WriteConsoleA, stdout, ADDR yes, sizeof yes, ADDR cWritten, 0
    exit:
    invoke ExitProcess,0  
    end start
    

    Конструкция из 3 xor позволяет поменять значения в регистрах, и по окончании в регистре ah будет содержаться число 20. Затем выведется сообщение о том, что число четное.

    Также отметим конструкцию xor ah, ah — она позволяет обнулить регистр. По сути это аналог команды mov ah, 0, но программисты любят использовать именно эту конструкцию, так как она занимает всего 2 байта, а команда mov — 5 байт.

    Заключение

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

    Скачать исходник 1
    Скачать исходник 2

Опубликовано вAssembler

Будьте первым, кто оставит комментарий

    Добавить комментарий