-
Notifications
You must be signed in to change notification settings - Fork 0
/
ft_atoi_base.s
155 lines (131 loc) · 3.23 KB
/
ft_atoi_base.s
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
global ft_atoi_base
extern ft_strlen
section .data
wspace: db 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x20, 0x2B, 0x2D, 0x00
section .text
; ========== entrypoint ===============
ft_atoi_base: ; rdi = char *str, rsi = char *base
enter 0, 0
cmp rdi, 0x0
je ft_atoi_base_error
cmp rsi, 0x0
je ft_atoi_base_error
push rdi
push rsi
mov rdi, rsi
mov rsi, wspace
call ft_atoi_check_base
pop rsi
pop rdi
mov QWORD r8, 0
mov QWORD r9, 1
cmp rax, 0
je ft_atoi_base_error
call ft_atoi_compute_result
leave
ret
; ==================== boolean ret tools =================
ft_atoi_base_error:
xor rax, rax
mov rax, 0
leave
ret
ft_atoi_base_success:
xor rax, rax
mov rax, 1
leave
ret
; =========== is in string (white-space / base) ==========
ft_atoi_check_is_in_string: ; rdi = char *string_to_check, rsi = char *white-space / *base
enter 8, 0
xor rax, rax
mov QWORD [rsp], 0
mov r10b, BYTE [rdi] ; extract first character of rdi (string_to_check)
ft_atoi_check_is_in_string_loop:
mov rax, [rsp]
cmp BYTE [rsi+rax], 0
jz ft_atoi_is_in_string_exit_nofind
cmp r10b, BYTE [rsi+rax]
je ft_atoi_is_in_string_exit_find
add DWORD [rsp], 1
jmp ft_atoi_check_is_in_string_loop
ft_atoi_is_in_string_exit_find:
leave
ret
ft_atoi_is_in_string_exit_nofind:
mov QWORD rax, -1
leave
ret
; =============== Atoi check base =============
ft_atoi_check_base: ; rdi = char *base, rsi = char *wspace
enter 8, 0
push rdi
call ft_strlen
pop rdi
cmp rax, 1
jle ft_atoi_base_error
xor rax, rax
xor rcx, rcx
mov QWORD [rsp], rdi ; continue to next function
ft_atoi_check_base_syntax_wspace_loop:
mov r10b, BYTE [rdi]
cmp r10b, 0
jz ft_atoi_check_base_middle
call ft_atoi_check_is_in_string
cmp rax, -1
jne ft_atoi_base_error
inc rdi
jmp ft_atoi_check_base_syntax_wspace_loop
ft_atoi_check_base_middle:
mov rdi, QWORD [rsp]
ft_atoi_check_base_syntax_unique_loop:
mov r10b, BYTE [rdi]
cmp r10b, 0
jz ft_atoi_base_success
inc rcx
mov dl, BYTE [rdi+rcx]
cmp r10b, dl
je ft_atoi_base_error
cmp BYTE [rdi+rcx], 0
jne ft_atoi_check_base_syntax_unique_loop
mov QWORD rcx, 0
inc rdi
jmp ft_atoi_check_base_syntax_unique_loop
; =========== Compute result =============
ft_atoi_compute_result: ; rdi = char *str, rsi = char *base
enter 8, 0
push rsi
mov rsi, wspace ; continue to next function
ft_atoi_compute_result_while_wspace: ; rdi = char *str, rsi = char *wspace
cmp BYTE [rdi], 0
je ft_atoi_compute_result_middle
call ft_atoi_check_is_in_string
cmp rax, -1
je ft_atoi_compute_result_middle
mov r10b, BYTE [rdi]
inc rdi
cmp r10b, '-'
jne ft_atoi_compute_result_while_wspace
imul r9, -1
jmp ft_atoi_compute_result_while_wspace
ft_atoi_compute_result_middle:
pop rsi ; contine to next function
ft_atoi_compute_result_final_loop:
cmp BYTE [rdi], 0
je ft_atoi_base_final
call ft_atoi_check_is_in_string
cmp rax, -1
je ft_atoi_base_final
mov QWORD [rsp], rax
xchg rdi, rsi
call ft_strlen
xchg rdi, rsi
imul r8, rax
add r8, QWORD [rsp]
inc rdi
jmp ft_atoi_compute_result_final_loop
ft_atoi_base_final:
imul r8, r9
mov QWORD rax, r8
leave
ret