# Logical Operations

Just like shifting, there are other opertions on bits such as `and`, `or`, `xor` and `not`. With those operations, one can manipulate each bit of a data.

Operation Usage Description
`and` `and eax, edx` Each i-th bit in `eax` and `edx` will be compared and the i-th bit of `eax` will be `1` iff both compared bits are `1`
`or` `or eax, edx` Each i-th bit in `eax` and `edx` will be compared and the i-th bit of `eax` will be `1` if at least one of the compared bits is `1`
`xor` `xor eax, edx` Each i-th bit in `eax` and `edx` will be compared and the i-th bit of `eax` will be `1` iff one of the compared bits is `1` and the other `0`
`not` `not eax` Inverts each bit in `eax`
`test` `test eax, edx` Same as `and eax, edx`, changes the FLAGS only, but not the registers

## Use

signchanger.asm

``````segment .text
global changeSign

changeSign:
mov eax, [esp + 4]  ; get argument
NOT eax                 ; invert arg
INC eax                 ; eax++
ret``````

This code multiplies any number with `-1` much faster than a multiplication operation by just using a bit operation and an increment. So the function changes signs of any number in two's complement.

signChanger-alt.asm

``````segment .text
global changeSign

changeSign:
mov eax, [esp + 4]  ; get argument
NEG eax                 ; negate
ret``````

This is the recommended and actually used way to change the sign. The first example was only to show an example for logical operations.

## Bitwise Manipulation

Sometimes it might be necessary to change a specific bit of a value. So let us assume our value is stored in `eax`.

Operation Code
Turn on bit i `OR eax, n` where `n = 2^i`
Turn off bit i `AND eax, n` where `n = NOT (2^i)`
Invert bit i `XOR eax, n` where `n = 2^i`
Clear register `XOR eax, eax`

Let us take the following function `size_t getAbsolute(uint32_t value)` which returns the absolute value of the entered value as an example.

absolute.asm

``````segment .text
global getAbsolute

getAbsolute:
mov eax, [esp + 4]  ; get argument
TEST eax, 0x80000000
JZ  return
NEG eax
return:
ret``````