Skip to content

Commit 02abfd9

Browse files
authored
Merge pull request mouredev#3762 from evanz2608/main
#6 - NASM
2 parents 7146777 + b75d00a commit 02abfd9

File tree

1 file changed

+132
-0
lines changed

1 file changed

+132
-0
lines changed
+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
; https://nasm.us/
2+
3+
; ====================================================================
4+
; Ejercicio 06 - Recursividad
5+
; ====================================================================
6+
;
7+
; Simplemente aclarar que existen dos tipos de recursividad: Directa e Indirecta.
8+
; La recursividad directa se da cuando una función se llama a sí misma, y la recursividad indirecta se da cuando una función A llama a una función B
9+
; que a su vez llama a la función A.
10+
11+
12+
SYS_read: equ 0
13+
SYS_write: equ 1
14+
SYS_exit: equ 60
15+
STDIN: equ 0
16+
STDOUT: equ 1
17+
STDERR: equ 2
18+
19+
20+
global _start
21+
extern printf
22+
section .text
23+
24+
_start:
25+
mov rdi, 100
26+
call recursion1
27+
28+
lea rdi, [LF]
29+
call printf
30+
lea rdi, [LF]
31+
call printf
32+
33+
%define FIB_ELEM 30
34+
mov rdi, FIB_ELEM
35+
call fibonacci
36+
mov rdx, rax
37+
mov rsi, FIB_ELEM
38+
lea rdi, [fibonacci_mask]
39+
call printf
40+
41+
%define FACT_NUM 10
42+
mov rdi, FACT_NUM
43+
call factorial
44+
mov rdx, rax
45+
mov rsi, FACT_NUM
46+
lea rdi, [factorial_mask]
47+
call printf
48+
49+
_exit:
50+
mov rax, SYS_exit
51+
xor rdi, rdi
52+
syscall
53+
54+
; En esta función, primero preparamos el stack para poder hacer el CALL tanto a printf, como a la próxima iteración
55+
; de recursion1.
56+
; En ensamblador, es necesario que es stack esté alineado a 16 bytes, y cada vez que se usa CALL, el stack se desalinea
57+
; puesto que CALL guarda en el stack la dirección de retorno, y por consiguiente, se le resta 8 bytes a RSP.
58+
; Como en este caso tenemos dos llamadas, el stack sigue alineado, pero nesecitamos crear un "STACK FRAME", para que cada llamada
59+
; guarde su punto de regreso sin corromper el punto guardado por la llamada anterior.
60+
recursion1:
61+
push rbp
62+
mov rbp, rsp
63+
sub rsp, 16
64+
mov rcx, rdi
65+
mov [rbp - 16], rcx
66+
lea rdi, [printf_mask]
67+
mov rsi, rcx
68+
call printf
69+
mov rcx, [rbp - 16]
70+
dec rcx
71+
mov rdi, rcx
72+
test rcx, rcx
73+
jz .done
74+
call recursion1
75+
.done:
76+
add rsp, 16
77+
pop rbp
78+
ret
79+
80+
; RDI: posición del elemento de la sucesión de Fibonacci a calcular.
81+
; NOTA: esta función es muy lenta. Se puede optimizar bastante puesto que para cada recursión calcula
82+
; todos los numeros de fibonacci anteriores.
83+
fibonacci:
84+
push rbp
85+
mov rbp, rsp
86+
sub rsp, 32
87+
mov [rbp - 32], rdi
88+
89+
cmp rdi, 1
90+
mov rax, rdi
91+
jle .return
92+
sub rdi, 1
93+
call fibonacci
94+
mov [rbp - 16], rax
95+
mov rdi, [rbp - 32]
96+
sub rdi, 2
97+
call fibonacci
98+
add rax, [rbp - 16]
99+
jmp .return
100+
.return:
101+
add rsp, 32
102+
pop rbp
103+
ret
104+
105+
; RDI: el número del cual se va a calcular el factorial.
106+
factorial:
107+
push rbp
108+
mov rbp, rsp
109+
sub rsp, 32
110+
mov [rbp - 32], rdi
111+
cmp rdi, 1
112+
jg .calculate
113+
mov rax, 1
114+
jmp .return
115+
.calculate:
116+
dec rdi
117+
call factorial
118+
inc rdi
119+
mul rdi
120+
jmp .return
121+
.return:
122+
add rsp, 32
123+
pop rbp
124+
ret
125+
126+
section .data
127+
printf_mask: db "%d ", 0x00
128+
fibonacci_mask: db "El elemento [%d] de fibonacci es: %d", 0x0A, 0x00
129+
factorial_mask: db "El factorial de [%d] es: %d", 0x0A, 0x00
130+
LF: db 0x0A, 0x00
131+
132+
section .bss

0 commit comments

Comments
 (0)