# Common Logic Structures

When analyzing code, it’s important to recognize basic flow control structures.

* Remember that the decompiler may be unreliable.

Basic structures:

* If else
* Switch case
* For

## Conditional Branches (if else)

Basic control-flow instructions: move execution to a defined address if a condition is true.

* Usually, one condition is tested at a time. Complex If/else must be broken.

Assembly code is structured **as a graph with tests and execution** statements (the body of the condition).

x86 and most architectures have inherent support for many types of comparisons.

* In x86 this is the jXX family of instructions.

<figure><img src="/files/TF9JY2pJnFVxp5jSu6BI" alt=""><figcaption></figcaption></figure>

<figure><img src="/files/h163Axp2VN3WkGJhNdbm" alt=""><figcaption></figcaption></figure>

* Signed comparison: `l < , le <=, g >, ge >=`
* Unsigned comparison: `b <, be <=, a >=, ae >=`
  * Below and Above.
* Equality `e`
* Every condition can be negated with `n`
* z, s, c, o, and p for ZF, SF, CF OF, and PF
  * **ZF: Zero Flag**, 1 if the last operation was 0.
  * **CF: Carry Flag.** The last operation required an additional bit (e.g. 255 + 1, which has 9 bits).
  * **OF: Overflow Flag**. The last operation had an arithmetic overflow (127 + 127 in a signed variable results in overflow).
  * **PF: Parity Flag**. 1 if the last operation resulted in a value with an even number of 1.
  * **SF: Sign Flag**. 1 if the last operation resulted in a signed value (MSB bit = 1)
* s means negative, ns non-negative.
  * Signal or not signal.
* p and np are also pe “parity even” and po “parity odd”.
* and, or, and xor clear OF and CF, and set ZF, SF, and PF based on the result.
* `test` is like `and` but only sets the flags discarding the result.
* Checking `nz` after `test` is like `if (x & mask) in C`
* `test` a register against itself is the fastest way to check for zero or negative.

**Direct jump**: target(s) specified in code (harcoded).

**Indirect jump**: target selected from runtime data like register or memory contents.

**Conditional jump**: target differs based on a condition.

<figure><img src="/files/ay4lXes6OXsxjjWPDCdc" alt=""><figcaption></figcaption></figure>

Structure can be recognized by one or more conditional branches, without loops.

je: jump equal.

js: jump is sign.

## Switch case

<figure><img src="/files/aahTf2tDrTSRb2jG5oYb" alt=""><figcaption></figcaption></figure>

A structure can be recognized by several comparisons and jumps or **jump tables**.

Observe the difference between what a programmer writes and what is produced.

* A switch is written as an atomic instruction, but it isn’t.
* Also, it is dangerous because of missing breaks.

Test: compare two registers. Set 3 flags:

* PF: Even the number of bits
* ZF: Zero
* SF: Signed value

## loops

<figure><img src="/files/pN78xR00H7n6VChsYgAJ" alt=""><figcaption></figcaption></figure>

For, while and do while are generally the same.

Identified by:

* an index.
* an increment.
* a comparison.
* two jumps.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://davidjosearaujo.gitbook.io/notes-mcs/reverse-engineering/binary-analysis/common-logic-structures.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
