aboutsummaryrefslogtreecommitdiff
path: root/ft_atoi_base.s
blob: 624576559bec3ec657f99ffb10a1d1167c0a27a3 (plain)
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
# **************************************************************************** #
#                                                                              #
#                                                         :::      ::::::::    #
#    ft_atoi_base.s                                     :+:      :+:    :+:    #
#                                                     +:+ +:+         +:+      #
#    By: cacharle <marvin@42.fr>                    +#+  +:+       +#+         #
#                                                 +#+#+#+#+#+   +#+            #
#    Created: 2019/11/22 03:59:15 by cacharle          #+#    #+#              #
#    Updated: 2019/11/22 21:18:08 by cacharle         ###   ########.fr        #
#                                                                              #
# **************************************************************************** #

.globl _ft_atoi_base
.globl _check_base

# int ft_atoi_base(const char*, const char*);
_ft_atoi_base:
	push rbp      # save previous stackframe
	mov rbp, rsp  # create new one

	mov rbx, rdi  # rbx = str
	mov rcx, rsi  # rcx = base

	mov rdi, rcx
	call _check_base
	cmp rax, 0
	je CHECK_BASE_ERROR

	mov rdi, rcx
	call _ft_strlen 
	#mov r8, rax  # r8 = radix
	#mov rax, r8

	xor rdx, rdx  # rdx = 0
	FT_ATOI_BASE_SPACE_LOOP:  # remove spaces
		mov rdi, [rbx]
		call ft_isspace
		cmp rax, 1
		jne FT_ATOI_BASE_SPACE_LOOP_END
		inc rbx
		jmp FT_ATOI_BASE_SPACE_LOOP
	FT_ATOI_BASE_SPACE_LOOP_END:

	xor rax, rax  # rax = 0
	xor rdx, rdx  # rdx = 0
	FT_ATOI_BASE_LOOP:
		cmp byte ptr [rbx], 30h # while isdigit
		jl FT_ATOI_BASE_END     # if *rbx < '0' jmp end
		cmp byte ptr [rbx], 39h
		ja FT_ATOI_BASE_END     # if *rbx > '9' jmp end

		imul eax, 10            # eax *= 10, shift previous digits
		mov dl, byte ptr [rbx]
		and dl, 0x0F            # char to digit
		add eax, edx            # insert as first digit
		inc rbx
		jmp FT_ATOI_BASE_LOOP
	FT_ATOI_BASE_END:
	pop rbp
	ret
		
_base_pos:
	mov rcx, rsi
	xor rax, rax
	BASE_POS_LOOP:
		cmp byte ptr [rdi + rax], 0
		je BASE_POS_NOT_FOUND
		cmp cl, byte ptr [rdi + rax]
		je BASE_POS_FOUND
		inc eax
		jmp BASE_POS_LOOP
	BASE_POS_NOT_FOUND:
		mov eax, 0xFFFFFFFF
	BASE_POS_FOUND:
		ret

_check_base:
	push rbx
	mov rbx, rsp

	mov rbx, rdi  # rbx = str

	call _ft_strlen  # f strlen(rbx) < 2
	cmp eax, 2
	jl CHECK_BASE_ERROR

	CHECK_BASE_LOOP:
		cmp byte ptr [rbx], 2bh  #  *rbx == '-' || *rbx == '+'
		je CHECK_BASE_ERROR
		cmp byte ptr [rbx], 2dh
		je CHECK_BASE_ERROR
		call ft_isspace
		cmp rax, 1
		je CHECK_BASE_ERROR
			
		inc rbx
		cmp byte ptr [rbx], 0h
		jne CHECK_BASE_LOOP
	mov rax, 1
	pop rbx
	ret
	CHECK_BASE_ERROR:
		xor rax, rax
		pop rbx
		ret

ft_isspace:
	cmp byte ptr [rdi], 20h  # if space jump next
	je ISSPACE_TRUE_END
	mov dl, byte ptr [rdi]  # if \t\n\r\v\f jump next
	sub dl, 9h
	cmp dl, 5h
	jl ISSPACE_TRUE_END
	xor rax, rax
	ret
	ISSPACE_TRUE_END:
		mov rax, 1
		ret