extern void op1(void);
extern void op2(void);
void decision(int x) {
	if (x) {
    	op1();
    }
    else {
    	op2();
    }
}
decision :
	subq	$8, %rsp
    test1	%edi, %edi
    je		.L2
    call 	op1
    jmp		.L1
.L2 :
	call	op2
.L1 :
	addq	$8, %rsp
    ret
(Information about currently executing program)
addq src, dst <=> t = a + b
CF : carry flag (for unsigned)
: 가장 최근 연산에서 MSB로부터 받아 올림이 발생한 것 표시. unsigned 연산에서 오버플로우 검출할 때 사용
if (t < a)
ZF : zero flag
: 가장 최근 연산의 결과가 0인 것을 표시
if t == 0
SF : sign flag (for signed)
: 가장 최근 연산이 음수를 생성한 것을 표시
MSB가 1이면 음수라고 판단한다.
if t < 0
OF : overflow flag (for signed)
: 가장 최근 연산이 양수/음수의 2의 보수 오버플로우를 발생시킨 것을 표시
if (a>0 && b>0 && t<0) || (a<0 && b<0 && t>=0)
cmp a, b
test a, b
Computes a&b (just like and)
Sets condition codes (only SF and ZF) based on result
common use : test %rX, %rX to compare %rX to zero
common use 2 : test %rX, %rY to test if any of 1-bits in %rY are also 1 in %rX (or vice versa)
| jX | Condition | Description | 
|---|---|---|
| jmp | 1 | Unconditional | 
| je | ZF | Equal / Zero | 
| jne | ~ZF | Not Equal / Not Zero | 
| js | SF | Negative | 
| jns | ~SF | Nonnegative | 
| jg | Greater | |
| jge | Greater or Equal | |
| jl | Less | |
| jle | Less or Equal | |
| ja | Above (unsigned) | |
| jb | below (unsigned) | 
| SetX | Condition | Description | 
|---|---|---|
| sete | ZF | Equal / Zero | 
| setne | ~ZF | Not Equal / Not Zero | 
| sets | SF | Negative | 
| setns | ~SF | Nonnegative | 
| setg | Greater | |
| setge | Greater or Equal | |
| setl | Less | |
| setle | Less or Equal | |
| seta | Above (unsigned) | |
| setb | Below (unsigned) | 
int gt(long x, long y) {
	return x > y;
}
x in %rdi, y in %rsi, return value in %rax
cmp		%rsi, %rdi		// Compare x : y	 (y - x)
setg	%al				// Set when >
movzbl %al, %eax		// Zero rest of %rax
long absdiff(long x, long y) {
	long result;
    if (x > y) 
    	result = x - y;
    else
    	result = y - x;
    return result;
}
x in %rdi, y in %rsi
absdiff :
	comp %rsi, %rdi		// Compare x : y
    jle .L4
    movq %rdi, %rax		// %rax = x
    subq %rsi, %rax		// $rax = %rax - %rsi  (x - y)
    ret
.L4 :					// x <= y
	movq %rsi, %rax		// %rax = y
    subq %rdi, %rax		// %rax = %rax - %rdi (y - x)
    ret
long pcount_do(unsigned long x) {
	long result = 0;
    do {
    	result += x & 0x1;
        x >> 1;
    } while (x);
    
    return result;
}
long pcount_goto(unsigned long x) {
	long result = 0;
    loop :
    	result += x & 0x1;
        x >> 1;
    if (x) goto loop;
    
    return result;
}
x in %rdi, result in %rax
	movl	$0, %rax	// result = 0
.L2 :
	movq	%rdi, %rdx	// %rdx = x
    andl	$1, %rdx	// %rdx = x & 1.
    addq	%rdx, %rax	// result += x&1
    shrq	%rdi		// x >>= 1
    jne		.L2			// if (x) goto loop
    rep; ret
long pcount_while(unsigned long x) {
	long result = 0;
    while (x) {
    	result += x & 0x1 ;
        x>> 1;
    }
    return result;
}
long pcount_goto_jtm(unsigned long x) {
	long result = 0;
    goto test
    
   loop :
    result += x & 0x1;
    x >> 1;
   
   test :
    if (x) goto loop;
    return result;
long pcount_goto_dw(unsigned long x) {
	long result = 0;
    if (!x) goto done;
   
   loop :
    result += x & 0x1;
    x >>= 1;
    if (x) goto loop;
   
   done:
    return result;
}
long switch_eg(long x, long y, long z) {
	long w = 1;
    
    switch(x) {
    	case 1 :
        	w = y * z;
            break;
        case 2 :
        	w = y / z;
            /* Fall Throuh */
        case 3 :
        	w += z;
            break;
        case 5 :
     	case 6 :
        	w -= z;
            break;
        default :
        	w = 2;
        }
        
        return 2;
}
x in %rdi, y in %rsi, z in %rdx, return value in %rax
//setup
swtich_eq :
	movq	%rdx, %rcx	// %rcx = z
    cmpq	$6, %rdi	// x : 6 비교
    ja		.L8			// 6보다 크면 default값을 가지게 한다.
    
    jmp		* .L4(, %rdi, 8) // goto *JTap[x]. Indirect Jump
<jump table>
.section .rodata
		 .align 8
         
.L4
		 .quad	.L8	// x = 0
         .quad	.L3 // x = 1
         .quad	.L5 // x = 2
         .quad	.L9 // x = 3
         .quad	.L8 // x = 4
         .quad	.L7 // x = 5
         .quad	.L7 // x = 6
Jumping
- direct : **jmp .L8**	
     - Jump target is denoted by label **.L8**
- indirect : **jmp *.L4(, %rdi, 8)**
   - Start of jump table : .L4
   - Must scale by factor of 8 (addresses are 8 bytes)
   - Fetch target from effective Address .L4 + x*8
   - only for 0 <= x <= 6
   
나머지 이어서
.L3 :
movq %rsi, %rax		// %rax = y
imulq %rdx, %rax	// %rax = y * z
ret
.L5 :
movq %rsi, %rax		// %rax = y
cqto
idivq	%rcx		// y/z
jmp		.L6			// goto merge
.L9 :
movl	$1, %rax	// %rax = 1
.L6 :
addq	%rcx, %rax	// %rax += z
ret
.L7 :
movl	$1, %rax	// %rax = 1
subq	%rdx, %rax	// %rax -= z
ret
.L8 :
movl	$2, %rax	// %rax = 2
ret