# Conditionals

In this tutorial, we will look deeper into conditional branching. We have been doing this throughout the previous tutorials, so it will be easy to understand here. Usually, conditions are checked by comparisons via the `CMP` instruction.

## Conditional Instructions

After an arithmetic or logic instruction, or the compare instruction, cmp, the processor sets or clears bits in its rflags. The most interesting flags are:

```````s` (sign)
`z` (zero)
`c` (carry)
`o` (overflow) ``````

So after doing, say, an addition instruction, we can perform a jump, move, or set, based on the new flag settings. For example:

``````jz label    ; Jump to 'label' if the result of the operation was zero
cmovno x, y ; x ← y if the last operation did not overflow
setc x      ; x ← 1 if the last operation had a carry,
; but x ← 0 otherwise (x must be a byte-size register or memory location)``````

The conditional instructions have three base forms: `j` for conditional jump, `cmov` for conditional move, and `set` for conditional set. The suffix of the instruction has one of the 30 forms: `s ns z nz c nc o no p np pe po e ne l nl le nle g ng ge nge a na ae nae b nb be nbe` referring to the sign, zero, carry, overflow, parity flags or to equality, less, greater, above and below.

## C Code

Let us first look into the following while we will translate into ASM later.

``````int cond(int n){
if (n > 50)
n = 50;
else if(n == 50)
n--;
else if (n < 50)
n++;
return n;
}``````

## ASM Code

``````segment .text
global cond

cond:
mov eax, [esp + 4]  ; eax = n
CMP eax, 50
JG jmp_grt
JE jmp_eq
JL jmp_lss

jmp_grt:
mov eax, 50
JMP endif

jmp_eq:
DEC eax
JMP endif

jmp_lss:
INC eax
JMP endif   ; unnecessary, as next instruction anyways

endif:
ret``````

It is also possible to make it more efficient by replacing with the following code:

``````segment .text
global cond

cond:   ; Function begin
mov eax, dword [esp+4H]
CMP eax, 50
JG jmp_cond_cond0_grt

jmp_leq:
JZ jmp_cond_cond0_eq
jmp_lss:
INC eax
JMP endif

jmp_eq:
DEC eax
JMP endif

jmp_grt:
mov eax, 50

endif:
ret
; cond End of function``````

## Labeling

In a fully fledged assembly code, there will probably be multiple conditions in many places, so make sure to use such label names in a way that you won't lose track of things. So make up your own labelling convention or take the following:

Let `function` and `method` be two different functions with three conditions checked each.

Then take the first few letters (at least 4!) of the function appended by "_cond" and a number starting from zero (by order of the conditions) as the label for the condition. For any jumps, use that previous condition label prepended by "jmp_" and appended by "_eq", "_ne", "_leq", "_lss", "_geq", "_grt", "_z", "_c", "_s", "_o", etc. for equality, not equal, less or equal, less, greater or equal, greater, zero, carry, sign, overflow, etc. respectively. The end of the codition is labeled by "_endif" and the condition label. If there are conditions in conditions, you may change that condition number into two digits and append the sub-condition number to it. E.g.: For a function `function` with 2 conditions and 2 sub-conditions in first condition will result in `func_cond0` for first condition, `func_cond000` for first sub-condition, `func_cond001` for second sub-condition, and `func_cond1` for the second condition with no sub-conditions.

Example:

``````global function
global method

function:
mov eax, [esp + 4]
mov edx, [esp + 8]
func_cond0:
CMP eax, edx
JG  jmp_func_cond0_grt

func_cond0_leq:
JMP jmp_func_cond0_lss
; do something
JMP endif_func_cond0
jmp_func_cond0_lss:
; do something
JMP endif_func_cond0

jmp_func_cond0_grt:
; do something

endif_func_cond0:
; do something
func_return:
ret
; end function

method:
mov eax, [esp + 4]
mov edx, [esp + 8]
meth_cond0:
CMP eax, edx
JG  jmp_meth_cond0_grt

meth_cond0_leq:
JMP jmp_meth_cond0_lss
; do something
JMP endif_meth_cond0
jmp_meth_cond0_lss:
; do something
JMP endif_meth_cond0

jmp_meth_cond0_grt:
; do something

endif_meth_cond0:
; do something
CMP eax, edx    ; second comparison
JG jmp_meth_cond1_grt

meth_cond1_leq:
; do something

jmp_meth_cond1_grt:
mov eax, 0
meth_return:
ret
; end method``````