non leaf function tutorial added
This commit is contained in:
163
x86_64/5_nonleaf.asm
Normal file
163
x86_64/5_nonleaf.asm
Normal 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
|
||||||
Reference in New Issue
Block a user