+|
+
+```c
+int swap (long *xp, long *yp) {
+ long t0 = *xp;
+ long t1 = *yp;
+ *xp = t1;
+ *yp = t0;
+}
+```
+ |
+
+
+```nasm
+swap:
+ movq (%rdi), %rax
+ movq (%rsi), %rdx
+ movq %rdx, (%rdi)
+ movq %rax, (%rsi)
+ ret
+```
+ |
+
+
+
+Complete form of memory addressing modes:
+`D(Rb, Ri, S)` means `Mem[Reg[Rb] + S*Reg[Ri] + D]`
+* `D`: Constant "displacement"
+* `Rb`: Base Register
+* `Ri`: Index Register
+* `S`: Scale Factor(1, 2, 4, or 8)
+
+for example:
+
+| `%rdx` | `%rcx` |
+| -------- | -------- |
+| `0xf000` | `0x0100` |
+
+* `0x8(%rdx)` = `0xf008`
+* `(%rdx, %rcx)` = `0xf100`
+* `(%rdx, %rcx, 4)` = `0xf400`
+* `0x80(,%rdx, 2)` = `0x1e080`
+
+#### Arithmetic & Logical Operations
+
+* `leaq $src, $dst`
+ * computing address without memory reference like `p = &x[i]`
+ * computing arithmetic expression `x + k * y`
+
+* `addq $src, $dst`
+* `subq $src, $dst`
+* `imulq $src, $dst`
+* `salq $src, $dst`
+* `sarq $src, $dst`
+* `shrq $src, $dst`
+* `xorq $src, $dst`
+* `andq $src, $dst`
+* `orq $src, $dst`
+all the above operator operates like `dest = dest # src`
+
+* `incq $dest`
+* `decq $dest`
+* `negq $dest`
+* `notq $dest`
+
+## Control
+
+**Processor State(x86-64, Partial)**
+* Temporary data(`%rax`, ...)
+* Location of runtime stack(`%rsp`)
+* Location of current code control point(`%rip`, instruction point)
+* Status of recent tests(`CF`, `ZF`, `SF`, `OF`)
+
+### Condition Codes
+
+* Single bit registers
+ * `CF` Carry flag (for unsigned)
+ * `SF` Sign flag (for signed)
+ * `ZF` Zero flag
+ * `OF` Overflow flag (for signed)
+
+**Conditional Codes(Implicit Setting)**
+
+Implicit setting is codes are set by arithmetic operations(`addq`, `subq`, `mulq`)
+for example: `addq`: `t = a + b`
+* `CF` set if carry out from most significant bit or unsigned overflow
+* `ZF` set if `t == 0`
+* `SF` set if `t < 0` (as signed)
+* `OF` set if two's-complement overflow or signed overflow
+`(a > 0 && b > 0 && (a + b) < 0) || (a < 0 && b < 0 && (a + b) >= 0)`
+
+The codes are not implictly set by `leaq`, because it is not designed to be used as arithmetic but used as **address calculation**. so it cannot affect to conditional codes.
+
+**Conditional Codes(Explicit Setting)**
+
+The codes are set explictly by compare instruction.
+
+`cmpq b, a` is computing `a - b` without setting destination.
+
+* `CF` set if carry out from most significant bit or unsigned overflow
+* `ZF` set if `a == b` or `a - b == 0`
+* `SF` set if `(a - b) < 0` (as signed)
+* `OF` set if two's-complement overflow or signed overflow
+`(a > 0 && b > 0 && (a - b) < 0) || (a < 0 && b < 0 && (a - b) >= 0)`
+
+And explictly set by test instruction
+
+`testq b, a` is computing `a & b` without setting destination.
+
+Sets condition codes based on value of `a & b` it is useful to have one of the operands be a mask.
+
+* `ZF` set when `a & b == 0`
+* `SF` set when `a & b < 0`
+
+**Reading Condition Codes**
+
+`setX`: set single byte based on combination of condition codes
+
+| setX | effect | desc |
+| ------- | ---------------- | ------------------------- |
+| `sete` | `ZF` | Equal / Zero |
+| `setne` | `~ZF` | Not Equal / Not Zero |
+| `sets` | `SF` | Negative |
+| `setns` | `~SF` | Nonnegative |
+| `setg` | `~(SF^OF) & ~ZF` | Greater (signed) |
+| `setge` | `~(SF^OF)` | Greater or Equal (signed) |
+| `setl` | `SF^OF` | Less (signed) |
+| `setle` | `(SF^OF) \| ZF` | Less or Equal (signed) |
+| `seta` | `~CF & ~ZF` | Above (unsigned) |
+| `setb` | `CF` | Below (unsigned) |
+
+it deos not alter remaining bytes of registers. only use 1 byte register(`%al`, `%bl`)
+
+```nasm
+cmpq %rsi(y), %rdi(x) # compare x and y
+setg %al # set when >(greater)
+movzbl %al, %eax # move zero extend byte to long
+ret
+```
+
+### Conditional Branches
+
+#### Jumping
+
+`jX` jump to different part of code depending on condition codes.
+
+| jX | condition | desc |
+| ----- | ---------------- | ------------------------- |
+| `jmp` | 1 | Unconditional |
+| `je` | `ZF` | Equal / Zero |
+| `jne` | `~ZF` | Not Equal / Not Zero |
+| `js` | `SF` | Negative |
+| `jns` | `~SF` | Nonnegative |
+| `jg` | `~(SF^OF) & ~ZF` | Greater (signed) |
+| `jge` | `~(SF^OF)` | Greater or Equal (signed) |
+| `jl` | `SF^OF` | Less (signed) |
+| `jle` | `(SF^OF) \| ZF` | Less or Equal (signed) |
+| `ja` | `~CF & ~ZF` | Above (unsigned) |
+| `jb` | `CF` | Below (unsigned) |
+
+Old Style Conditional Branch
+
+```c {cmd=gcc args=[-Og -x c -fno-if-conversion -c $input_file -o 3_3.o]}
+long absdiff(long x, long y) {
+ long result;
+ if (x > y) result = x - y;
+ else result = y - x;
+ return result;
+}
+```
+
+```sh { cmd hide }
+while ! [ -f 3_3.o ]; do sleep .1; done; objdump -d 3_3.o -Msuffix
+```
+
+**expressing with `goto`**
+
+```c {cmd=gcc args=[-Og -x c -fno-if-conversion -c $input_file -o 3_4.o]}
+long absdiff_j(long x, long y) {
+ long result;
+ int ntest = x <= y;
+ if (ntest) goto Else;
+ result = x-y;
+ goto Done;
+Else:
+ result = y-x;
+Done:
+ return result;
+}
+```
+
+#### Conditional Move
+
+But this branchings are very disruptive to instruction flow through pipelines, **Conditional Moves** are highly used because they do not require control transfer.
+
+```c {cmd=gcc args=[-O3 -x c -c $input_file -o 3_5.o]}
+long absdiff(long x, long y) {
+ long result;
+ if (x > y) result = x - y;
+ else result = y - x;
+ return result;
+}
+```
+
+```sh {cmd hide}
+while ! [ -f 3_5.o ]; do sleep .1; done; objdump -d 3_5.o -Msuffix
+```
+
+However, there are several *bad cases* for conditional move.
+
+* expansive computations
+```c
+val = Test(x) ? Hard1(x) : Hard2(x);
+```
+because both values are get computed. only simple computations are effective for conditional moves.
+* risky computations
+```c
+val = p ? *p : 0;
+```
+both values get computed may have undesiarable effects.
+* Computations with side effects
+```c
+val = x > 0 ? x*=7 : x+=3;
+```
+each expression has side-effect.
+
+### Loop
+
+#### do-while
+
+
+
+|
+
+```c
+for (Init; Test; Update) {
+ Body
+}
+```
+ |
+
+
+```c
+Init;
+while(Test) {
+ Body
+ Update;
+}
+```
+ |
+
+
+|
+
+```c {cmd=gcc args=[-O3 -x c -c $input_file -o 3_9.o]}
+#include
+#define WSIZE 8 * sizeof(int)
+
+long pcount_for(unsigned long x) {
+ size_t i;
+ long result = 0;
+ for (i = 0; i < WSIZE; i++) {
+ unsigned bit = (x >> i) & 0x1;
+ result += bit;
+ }
+ return result;
+}
+```
+ |
+
+```c {cmd=gcc args=[-O3 -x c -c $input_file -o 3_10.o]}
+#include
+#define WSIZE 8 * sizeof(int)
+long pcount_for(unsigned long x) {
+ size_t i;
+ long result = 0;
+ i = 0;
+ while(i < WSIZE) {
+ unsigned bit = (x >> i) & 0x1;
+ result += bit;
+ i++;
+ }
+ return result;
+}
+```
+ |
+
+
+|
+
+```sh {cmd hide}
+while ! [ -f 3_9.o ]; do sleep .1; done; objdump -d 3_9.o -Msuffix
+```
+ |
+
+
+```sh {cmd hide}
+while ! [ -f 3_10.o ]; do sleep .1; done; objdump -d 3_10.o -Msuffix
+```
+ |
+
+
+
+for to do-while conversion, initial test can be optimized away.
+
+### Switch
+
+#### Jump Table Structure
+
+Switch form
+
+