aboutsummaryrefslogtreecommitdiff
path: root/ft_atoi_base.s
blob: e51487c933cb2b064877690da7802f66ae39faec (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
119
; **************************************************************************** ;
;                                                                              ;
;                                                         :::      ::::::::    ;
;    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        ;
;                                                                              ;
; **************************************************************************** ;

extern _ft_strlen

global _ft_atoi_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 [rbx], 30h ; while isdigit
		jl FT_ATOI_BASE_END     ; if *rbx < '0' jmp end
		cmp byte [rbx], 39h
		ja FT_ATOI_BASE_END     ; if *rbx > '9' jmp end

		imul eax, 10            ; eax *= 10, shift previous digits
		mov dl, byte [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 [rdi + rax], 0
		je BASE_POS_NOT_FOUND
		cmp cl, byte [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 [rbx], 2bh  ;  *rbx == '-' || *rbx == '+'
		je CHECK_BASE_ERROR
		cmp byte [rbx], 2dh
		je CHECK_BASE_ERROR
		call ft_isspace
		cmp rax, 1
		je CHECK_BASE_ERROR
			
		inc rbx
		cmp byte [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 [rdi], 20h  ; if space jump next
	je ISSPACE_TRUE_END
	mov dl, byte [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