This article covers the logical instructions supported in x86 assembly. Some of the logical instructions such AND, OR and XOR also have an effect on conditional flags like ZF and PF. So, we will also discuss how these logical instructions can also be used to control the flow of the program.

Programming with logical instructions in x86 assembly

The logical instructions perform basic logical operations on their operands. The following table illustrates the mnemonics used in x86 assembly when writing assembly programs. While the first three instructions (AND, OR, XOR) in the preceding table perform binary operations, the NOT instruction performs unary operations. In the next few sections, we will discuss how each of these instructions can be used to perform logical operations when used in an assembly program.

Programing with binary operations in x86 assembly

A binary operation is performed on two operands to return a result. AND, OR and XOR are examples of instructions that perform binary operations. The following assembly program written in x86 assembly provides an overview of these binary operations and we will also discuss how they can also have an effect on the program’s control flow. The instructions within the .text section will get executed from the entry point, which is  _start.  The program has 4 sections within it. The first section performs logical and, the second section performs logical or, the third section performs logical exclusive or and the last section of the code gracefully exits the program. _start: ;logical and mov eax, 20 mov ebx, 0 and eax, ebx jnz _exit ;logical or mov eax, 20 or eax, ebx jz _exit ;logical xor xor eax, eax ;gracefully exit the program _exit: mov eax, 1 mov ebx, 0 int 0x80 We are initializing the registers eax and ebx using the following instructions.

mov eax, 20 mov ebx, 0

The next instruction and eax, ebx performs a binary operation, which is a bitwise and operation. The result of this operation will be zero and the output will be placed in the first operand, which is eax in this case. This instruction will also have effects on the condition flags as follows.

SF becomes the value of the most significant bit of the calculated result. ZF will be set if the result is 0. PF is set according to the result

In our case, the result is zero and thus the ZF will be set. We can use this effect to control the flow of the program by making use of instructions such JE, JNE, JZ, JNZ. In the preceding program, the program will execute the _exit routine if the ZF is not set. In this case, the ZF will be set and thus the instruction jnz _exit will not take the jump. Next, in preparation to demonstrate the OR instruction, we are once again initializing the EAX register with the value 20 using the following instruction.

mov eax, 20

Once this instruction is executed eax contains the value 20 and ebx register contains the value 0.  The OR instruction performs an exclusive or operation on the two operands and the result will be stored in the first operand. The or eax, ebx instruction in this case will store the value 20 in eax after the exclusive or operation. Once again the jump will not be taken when executing the jz _exit instruction as the ZF flag is not set by the previous instruction. Finally, the logical exclusive or (xor) operation is performed when xor instruction is executed. One use case of xor instruction is to zero out a register. So, when xor eax, eax instruction is executed, the eax register will contain the value 0.

Programming with unary operations in x86 assembly

In contrast to binary operations where two operands are used, a unary operation is an operation with only one operand. NOT is an example of an instruction that performs unary operation. The following assembly program written in x86 assembly provides an overview of unary operation. This will not have any effect on the conditional flags. The instructions within the .text section will get executed from the entry point, which is  _start.  We are initializing the register eax using the following instruction. _start: ;logical not mov eax, 20 not eax _exit: mov eax, 1 mov ebx, 0 int 0x80

mov eax, 20

The next instruction not eax performs a bitwise inversion of the value stored in the eax register. GDB shows the following in the eax register, before the not instruction is executed. After executing the not instruction, GDB shows the following in the eax register. Let us observe how this value is derived after performing a not operation on the decimal value 20. Following is the 32 bit binary equivalent of decimal 20. A bitwise not on the preceding value results in the following. Following is the hex equivalent of the preceding value. This is the value shown by GDB after the NOT instruction is executed.

Conclusion

This article has provided an overview of logic instructions AND, OR, XOR and NOT. The instructions AND, OR and XOR perform binary operations with two operands while the NOT instruction performs unary operations with just one operand. When AND, OR and XOR instructions have an effect on the conditional flags, which can be used to control the flow of the program, while the NOT instruction does not have any effect on these flags.  

Sources

Assembly Language for x86 Processors, Kip Irvine Modern X86 Assembly Language Programming, Daniel Kusswurm Linux Assembly Language Programming, Bob Neveln