long P(long x, long y) {
	long u = Q(y);
    long v = Q(x);
    return u + v;
}
P :
	// 먼저 두 레지스터의 값을 스택에 저장한다.
	pushq %rbp			// save %rbp. x를 보관한다.
    pushq %rbx			// save %rbx. Q(y)를 보관한다.
    
    subq $8, %rsp		// allign stack frame
    movq %rdi, %rbp 	// save x
    movq %rsi, %rdi		// move y to first argument
    call Q
    
    movq %rax, %rbx		// save result. Q 호출의 결과를 %rbx에 저장한다.
    movq %rbp, %rdi		// move x to first argument
    call Q
    addq %rbx, %rax		// add saved Q(y) to Q(x)
    addq $8, %rsp		// deallocate last part of stack
    
    // 두 피호출자-저장 레지스터의 값을 스택에서 pop해와서 복원한다. (역순임을 주의하자!!)
    popq %rbx			// restore %rbx
    popq %rbp			// restore %rbp
    ret
long call_incr2(long x) {
	long v1 = 351;
    long v2 = increment(&v1, 100);
    return x + v2;
}
call_incr2 :
	pushq	%rbx		// save %rbx. 먼저 레지스터 값을 스택에 저장
    subq	$16, %rsp	// 2 frame 공간을 만든다
    
    movq	%rdi, %rbx	// %rbx에 x값 저장. (%rdi는 1st argument register)
    movq	$351, 8(%rsp)	// 아까 frame 공간 만들었던 위쪽에 351 저장
    
    // 1st, 2nd argument register에 값을 넣어서 call 준비
    movl	$100, %esi		// %esi에 100 저장 
    leaq	8(%rsp), %rdi	// %rdi에 351 저장 (%rdi는 1st argument register)
  
  	call	increment
    
    addq	%rbx, %rax		// %rax(increment함수의 결과값)과 x 더해서 다시 %rax에 저장
    
    // 다시
    addq	$16, %rsp		// 2 frame 공간 없애
    popq	%rbx			// pop으로 복원
long rfact(long n) {
	long result;
    if (n <= 1)
    	result = 1;
    else
    	result = n * rfact(n-1);
    return result;
}
rfact :
	// 여기도 마찬가지로, %rbx 레지스터 사용하기 위해 일단 stack에 push해서 저장시켜둔다.
	pushq	%rbx
    movq	%rdi, %rbx			// %rbx에 n을 저장한다. (%rdi는 1st argument register)
    movl	$1, %eax			// %eax에 1 저장 (result = 1)
   
    cmpq	$1, %rdi			// n : 1 비교	
    jle		.L35				// 1 ≤ n이면 L35로 jump
    
    leaq	-1(%rdi), %rdi		// n = n-1
    call	rfact
    
    imulq	%rbx, %rax			// %rax(rfact의 return값) = %rax * n
.L35:
	popq	%rbx				// 다시 popq해서 저장해두었던 값 restore. restore %rbx
    ret
cmpq에서는 레지스터 순서를 바꿔서 비교한다는 걸 주의하자!!
long pcount_r(unsigned long x) {
	if (x == 0)
    	return 0;
    else
    	return (x&1) + pcount_r(x>>1);
}
pcount_r :
	movl $0, %eax		// %eax에 먼저 0을 저장해둔다. recursive 안들어가면 바로 return 0이니까
    
    testq %rdi, %rdi	// compare x : 0
    jne	.L8				// not equal이면 L8로 jump
    
    rep ret
.L8 :
	pushq %rbx			// %rbx 쓰려고 일단 스택에 저장시킴
    movq %rdi, %rbx		// %rbx에 x 저장
    
    // 함수 호출하기 전 1st argument 만져줌
    shrq %rdi			// x = x >> 1
    
    call pcount_r
    
    andl $1, %ebx		// x = x & 1
    addq %rbx, %rax		// %rax(pcount_r의 결과값) + x&1 더해서 %rax에 저장
    
    popq %rbx			// restore %rbx
    ret