> For the complete documentation index, see [llms.txt](https://w43l.gitbook.io/ctihandboook/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://w43l.gitbook.io/ctihandboook/learning-assembly/assembly-+-c-part-5.md).

# Assembly + C - Part #5

During my journey of learning Assembly, i was taking some notes .. and now, I'm sharing it openly with you <3 ...

<figure><img src="https://343128667-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH7rTfY2uPKTawTcEUhnW%2Fuploads%2Fqg3gzod2LGtS9qq4bk6o%2Fimage.png?alt=media&amp;token=851cb095-5d95-49cc-a78f-a3d5283acb1c" alt=""><figcaption></figcaption></figure>

## New Instructions: call, ret, mov, add, sub

Let's look at the following simple C code:

```
int func(){
	return 0xbeef;
}

int main(){
	func();
	return 0xf00d;
}
```

The generated assembly code for the previous c code is a as the following:

<figure><img src="https://343128667-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH7rTfY2uPKTawTcEUhnW%2Fuploads%2FkhAslrrJ58or22EwvFcd%2Fimage.png?alt=media&amp;token=380ed347-82be-494e-b412-19d16dbb9f25" alt=""><figcaption></figcaption></figure>

## CALL - Call Procedure

* CALL's job is to transfer control to a different function; in a way that control can later be resumed where it left off.
* First it *pushes* the address of the next instruction onto the stack.
  * For use by RET for when the procedure is done
* Then it changes RIP to the address given in the instruction.
* Destination address for the target function can be specified in multiple ways:
  * Absolute address
  * Relative address (relative to the end of the end instruction, or some other register)

## RET - Retrun from Procedure

* Two forms:
  * Pop the top of the stack into RIP (remember, pop implicitly increments stack point, RSP)
    * In this form, the instruction is just written as "ret".
  * Pop the top of the stack into RIP also add a constant number of bytes to RSP
    * In this form, the instruction is written as "ret 0x8" or "ret 0x20" etc.

## How to read two-operand instructions: Intel vs. AT\&T Syntax

### Intel : Destination <-- Source(s)

* Windows: Think algebra or C: y = 2x +1;

```
mov rbp, rsp
add rsp, 0x14; (rsp = rsp + 0x14)
```

### ATT\&T: Destination --> Source(s)

* \*nix/GNU: Think elementary school: 1 + 2 = 3

```
mov %rsp, %rbp
add $0x14, %rsp
```

* so registers get a % prefix and immediate get a $

> During my notes i'll use Intel syntax It's important to know both, so you can read documents in either format.

## MOV - Move

* Can move:
  * register to register
  * memory to register, register to memory
  * immediate to register, immediate to memory
* **But ! ... Never memory to memory**
* Memory addresses are given in "r/mX" form.

### "r/mX" Addressing Example

<figure><img src="https://343128667-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH7rTfY2uPKTawTcEUhnW%2Fuploads%2F56mXTp9qhC1jQzmkbXIe%2Fimage.png?alt=media&amp;token=7781d7f7-82da-4f68-9641-561fe8b06cae" alt=""><figcaption></figcaption></figure>

## ADD and SUB

* Adds or Substracts, just as expected
* Destination operand can be r/mX or register
* Source operand can be r/mX or register or immedaite
* No source **and** destination as r/mXs, because that could allow for memory to memory transfer, which isn't allowed on x86.

```
add rsp, 8 --> (rsp = rsp + 8)
sub rax, [rax*2] --> (rax = rax - memorypointedtoby(rbx*2))
```

## Stack frame single-step slideware wlakthrough

```
RIP = 00000001`40001010, but no instruction yet executed
```

1.

```
<figure><img src="/files/4PHyHMchgwdTKucTwwXj" alt=""><figcaption><p> </p></figcaption></figure>
```

2.

```
<figure><img src="/files/nU8SZ0LHfLHYs7KGuv0K" alt=""><figcaption></figcaption></figure>
```

3. ![](https://343128667-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH7rTfY2uPKTawTcEUhnW%2Fuploads%2FC65xZzzSH04dj7jtF1F7%2Fimage.png?alt=media\&token=5945100d-9944-42d4-ab2a-6f4e6d78c0fe)
4.

```
<figure><img src="/files/J8qslAHrdljqYLtvaH1Z" alt=""><figcaption></figcaption></figure>
```

```
> You can't tell, but it "zero extended" the rax reg (meaning it filled in the upper 32 bits of raw with zeros)
>
>

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

From section 3.4.1.1 in the Nov 2020 Intel Manual:
```

<figure><img src="https://343128667-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH7rTfY2uPKTawTcEUhnW%2Fuploads%2F37G4YHpW5uQLAyuokLTD%2Fimage.png?alt=media&amp;token=141eef8e-61a2-4614-9f49-255f2cffb105" alt=""><figcaption></figcaption></figure>

> NOTE: This only applies to writing to registers, not memory ! If you write a 32 bit value to what you're imagining as a "64-bit" memory location (such as for a 64 bit local variable), still only 32 bits will be changed !

### STACK FRAME TIME OUT

<figure><img src="https://343128667-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH7rTfY2uPKTawTcEUhnW%2Fuploads%2Fn5u4RmmiCxCH5aDf7Sep%2Fimage.png?alt=media&amp;token=2cf14e55-6234-4251-b918-e20301eaff6b" alt=""><figcaption></figcaption></figure>

Let's back to the execution

5\.&#x20;

<figure><img src="https://343128667-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH7rTfY2uPKTawTcEUhnW%2Fuploads%2F9zwF7XYb81CclOBwWh3E%2Fimage.png?alt=media&amp;token=345ed3c3-1836-4f58-89b3-41ce03c1b62b" alt=""><figcaption></figcaption></figure>

6\.&#x20;

<figure><img src="https://343128667-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH7rTfY2uPKTawTcEUhnW%2Fuploads%2F73Pp5MLPMvq1ye9zdzIP%2Fimage.png?alt=media&amp;token=3038acfa-3b33-4a6e-b842-e74f59c345b7" alt=""><figcaption></figcaption></figure>

7\.&#x20;

<figure><img src="https://343128667-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH7rTfY2uPKTawTcEUhnW%2Fuploads%2FJTxMnuEaSYndcJ05tWam%2Fimage.png?alt=media&amp;token=7c543afb-5a25-4125-9356-5c95e9a7a8cc" alt=""><figcaption></figcaption></figure>

8\.&#x20;

<figure><img src="https://343128667-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH7rTfY2uPKTawTcEUhnW%2Fuploads%2FyeG3AZXHQxll3dvJpG27%2Fimage.png?alt=media&amp;token=031cb835-e39b-497a-b314-3350fa1c212a" alt=""><figcaption></figcaption></figure>

### Notes

* `func()` is dead code - its return value is not used for anything, and main() always returns 0xF00D. If optimizations were turned on in the compiler, it would remove func().
* We don't yet understand why `main()` does `sub rsp, 28h` and `add rsp,28h`

#### Mystery Lister

With .. another mystery lister :D (will come to it later)

> Old: Why do the GCC/Clang HelloWorlds have balanced Push/Pop instruction but Visual Studio doesn't ?

* Wha'ts up with the `sub/add 0x28` in `main()`

### Simple Stack Diagram 2

Let's take the following C code:

```
#include <stdio.h>

int bar(int y) {
    int a = 3 * y;
    printf("bar returned %d", a);
    return a;
}

int foo(int x) {
    int b = 5 * x;
    printf("foo passed %d", b);
    return bar(b);
}

int main() {
    int c = foo(7);
    printf("main passed %d", c);
}
```

The stack will be as the following:

<figure><img src="https://343128667-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FH7rTfY2uPKTawTcEUhnW%2Fuploads%2FaN04tRnkws79n1rs0Xzm%2Fimage.png?alt=media&amp;token=6014bb05-3805-43df-92f4-623343426668" alt=""><figcaption></figcaption></figure>

## Instruction we now know

> NOP (6%) PUSH/POP (17%) CALL/RET (9%) MOV (23%) ADD/SUB (5%)

Now, we know probably **60%** from all of assembly instructions !! <3
