non leaf function tutorial added

This commit is contained in:
2019-08-13 18:59:36 +02:00
parent 8c7fbd1761
commit 26379ad01f

163
x86_64/5_nonleaf.asm Normal file
View File

@@ -0,0 +1,163 @@
global _start
section .bss
BUF_SIZE: equ 64
buf1: resb 64
buf2: resb 64
section .text
_start:
; Calling convention of a non leaf function is the same
; as a leaf function
mov rdi, 40579
mov rsi, buf1
mov rdx, BUF_SIZE
call uint2str
; write result to stdout
mov rdx, rax
mov rax, 1
mov rdi, 1
mov rsi, buf1
syscall
; Calculate !5
mov rdi, 5
call factorial
; Convert result to string
mov rdi, rax
mov rsi, buf2
mov rdx, BUF_SIZE
call uint2str
; Write !5 to stdout
mov rdx, rax
mov rax, 1
mov rdi, 1
mov rsi, buf2
syscall
; Exit
mov rax, 60
xor rdi, rdi
syscall
; size_t uint2str(unsigned number, char * buffer, size_t bufferSize)
; Returns the number of bytes written to the buffer
uint2str:
push rbp ; Store the rbp register on the stack
mov rbp, rsp ; Overwrite rbp with the function local stack pointer
; Backup the remaining callee saved registers
push rbx
push r12
push r13
push r14
push r15
; Overwrite the saved registers for demonstration purposes
mov r12, rdi ; number
mov r13, rsi ; buffer
mov r14, rdx ; bufferSize
xor r15, r15 ; counter
mov rax, r12 ; working copy of number
.loop:
cmp rax, 0
je .done ; n == 0
cmp r15, r14
jge .done ; i > BUF_SIZE
; n % 10
xor rdx, rdx
mov rdi, 10
div rdi ; rax = rax / rdi
add dl, '0' ; rdx = rax % rdi
mov byte [r13 + r15], dl
inc r15
jmp .loop
.done:
mov byte [r13 + r15], 0x0a ; append newline
inc r15
; Call reverse string routine to fix the order
mov rdi, r13 ; buffer
lea rsi, [r15 - 1] ; number of characters written, excluding newline
call revstr
mov rax, r15
; Restore saved registers
pop r15
pop r14
pop r13
pop r12
pop rbx
; restore rsp from rbp
mov rsp, rbp
pop rbp ; restore rbp
ret
; unsigned factorial(unsigned n)
; recursive!
factorial:
; save registers
push rbp
mov rbp, rsp
push rbx
push r12
push r13
push r14
push r15
mov r12, rdi; n
cmp r12, 0
je .zero
mov rbx, rdi
dec rdi
call factorial ; recursion!
xor rdx, rdx
mul rbx
jmp .done
.zero:
mov rax, 1 ; !0 = 1
.done:
; Restore saved registers
pop r15
pop r14
pop r13
pop r12
pop rbx
; restore rsp from rbp
mov rsp, rbp
pop rbp ; restore rbp
ret
; void revstr(char * s, size_t size)
revstr:
xor r8, r8 ; lowerbound
lea r9, [rsi - 1] ; upperbound
.loop:
cmp r8, r9
jge .done
mov cl, byte [rdi + r8] ; tmp = s[lowerbound]
xchg cl, byte [rdi + r9] ; tmp <-> s[upperbound]
mov byte [rdi + r8], cl ; s[lowerbound] = tmp
inc r8
dec r9
jmp .loop
.done:
ret