-
Notifications
You must be signed in to change notification settings - Fork 0
/
task3.asm
139 lines (118 loc) · 4 KB
/
task3.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
section .data
prompt db 'Enter a number (0-12): ', 0
result_msg db 'Factorial is: ', 0
newline db 10, 0
input_buffer db 10 dup(0) ; Buffer for user input
result_buffer db 20 dup(0) ; Buffer for result output
section .bss
; Empty for this program
section .text
global _start
_start:
; Display prompt
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, prompt
mov rdx, 22 ; Length of the prompt
syscall
; Read user input
mov rax, 0 ; sys_read
mov rdi, 0 ; stdin
mov rsi, input_buffer
mov rdx, 10 ; Max input size
syscall
; Convert input to integer
mov rsi, input_buffer ; Pass input buffer
call atoi ; Result in RAX
; Validate input (number between 0 and 12)
cmp rax, 12
ja invalid_input
cmp rax, 0
jl invalid_input
; Calculate factorial
push rax ; Push input number onto stack
call factorial
add rsp, 8 ; Clean up stack
; RAX now contains the factorial result
; Convert result to string
mov rsi, result_buffer ; Buffer for the result
call itoa
; Display result message
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, result_msg
mov rdx, 14 ; Length of the message
syscall
; Display result
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, result_buffer
mov rdx, 20 ; Assume max length
syscall
; Newline
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, newline
mov rdx, 1
syscall
; Exit program
mov rax, 60 ; sys_exit
xor rdi, rdi
syscall
invalid_input:
; Print an error message and exit
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, newline
mov rdx, 22 ; Error message
syscall
mov rax, 60 ; sys_exit
xor rdi, rdi
syscall
; Subroutine: Factorial Calculation
factorial:
mov rbx, 1 ; Initialize result in RBX
cmp rax, 0 ; If input is 0, return 1
je factorial_end
factorial_loop:
imul rbx, rax ; RBX = RBX * RAX
dec rax ; Decrement RAX
jnz factorial_loop
factorial_end:
mov rax, rbx ; Return result in RAX
ret
; Subroutine: ASCII to Integer Conversion (atoi)
atoi:
xor rax, rax ; Clear RAX
xor rcx, rcx ; RCX for multiplier (10^n)
mov rcx, 10
atoi_loop:
movzx rdx, byte [rsi] ; Load next character
cmp rdx, 10 ; Check for newline
je atoi_done
sub rdx, '0' ; Convert ASCII to digit
imul rax, rcx ; Multiply current result by 10
add rax, rdx ; Add digit to result
inc rsi
jmp atoi_loop
atoi_done:
ret
; Subroutine: Integer to ASCII Conversion (itoa)
itoa:
xor rcx, rcx ; Counter for digits
itoa_loop:
xor rdx, rdx ; Clear RDX
mov rbx, 10
div rbx ; Divide RAX by 10
add dl, '0' ; Convert remainder to ASCII
push rdx ; Store digit on stack
inc rcx
test rax, rax ; Check if RAX is 0
jnz itoa_loop
itoa_pop:
pop rdx ; Get digit from stack
mov [rsi], dl ; Store it in buffer
inc rsi
loop itoa_pop
mov byte [rsi], 0 ; Null-terminate the string
ret