Machine Language - Procedures & Recursion

Class: CSCE-312


Notes:

Caller-Saved Example

C code:

long compute(long a, long b)
	long c = a + 5;
	long d = mul(c, b);  // external function
	return d - a;

Assembly code (unsafe):

compute:
	movq %rdi, %rax   # copy a -> %rax
	addq $5, %rax     # c = a + 5
	movq %rax, %rdi   # ...
	movq %rsi, %rsi
	call mul
	subq %rdi, %rax
	ret

Safe option:

compute_safe:
	pushq %rdi        # save 'a'
	movq %rdi, %rax
	addq $5, %rax
	movq %rax, %rdi
	call mul
	popq %rdi         # restore 'a'
	subq %rdi, %rax
	ret

Callee-Saved Register

C code:

long calc_sum(long x) {
	long base = 100;
	long y = addn(&base, 2000);
	return y - x;
}

Assembly code:

# long calc_sum(long x)
calc_sum:
	pushq %rbx          # save callee-saved register
	subq $16, %rsp      # allocate 16 bytes for locals (make stack frame)
	movq %rdi, %rbx     # save x in %rbx
	movq $100, 8(%rsp)  # base = 100
	movq $2000, %esi    # 2nd arg: 2000
	leaq 8(%rsp), %rdi  # 1st arg: &base
	call addn           # addn(&base, 2000)
	subq %rbx, %rax     # y - x
	addq $16, %rsp      # deallocate locals
	popq %rbx           # restore callee-saved reg
	ret

Recursive Function Example

C code:

long fcat(long n) {
	if (n <= 1)
		return 1;
	else
		return n * fact(n - 1);
}

Assembly code:

# long fact(long n)
fact:
	movl $1, %eax        # base return value = 1
	cmpq $1, %rdi        # compare n wiht 1
	jle .Lbase           # if n <= , jump to base case
	
	pushq %rbx           # save callee-saved register
	movq %rdi, %rbx      # store n in %rbx
	subq $1, %rdi        # prepare argument(n - 1)
	call fact            # recursive call fact(n - 1)
	imulq %rbx, %rax     # multiply result * n
	popq %rbx            # restore %rbx
	ret
	
.Lbase:
	ret