feat: atoibase skel
This commit is contained in:
parent
12b8ab0bbc
commit
f8c8321615
1 changed files with 249 additions and 0 deletions
249
src/ft_atoibase.asm
Normal file
249
src/ft_atoibase.asm
Normal file
|
|
@ -0,0 +1,249 @@
|
||||||
|
global ft_atoibase
|
||||||
|
extern ft_bzero
|
||||||
|
extern ft_isspace
|
||||||
|
extern __errno_location
|
||||||
|
|
||||||
|
section .text
|
||||||
|
|
||||||
|
;int has_dup(const char *s) {
|
||||||
|
; uint32_t bits[8] = {0}; // 8*32 = 256 bits
|
||||||
|
; for (const unsigned char *p = (const unsigned char*)s; *p; ++p) {
|
||||||
|
; unsigned int v = *p;
|
||||||
|
; unsigned int idx = v >> 5; // division par 32
|
||||||
|
; unsigned int bit = v & 31; // v % 32
|
||||||
|
; uint32_t mask = 1u << bit;
|
||||||
|
; if (bits[idx] & mask) return -1;
|
||||||
|
; bits[idx] |= mask;
|
||||||
|
; }
|
||||||
|
; return 0;
|
||||||
|
;}
|
||||||
|
|
||||||
|
; return base_len and check for "-+" or duplicate char
|
||||||
|
; rdi: base
|
||||||
|
check_base:
|
||||||
|
; uint32_t buffer[8]
|
||||||
|
push rbp
|
||||||
|
mov rbp, rsp
|
||||||
|
sub rsp, 40
|
||||||
|
|
||||||
|
mov qword [rsp + 32], rdi
|
||||||
|
|
||||||
|
; bzero buffer, 32
|
||||||
|
mov rdi, rsp
|
||||||
|
mov rsi, 32
|
||||||
|
call ft_bzero wrt ..plt
|
||||||
|
|
||||||
|
mov rax, qword [rsp + 32]
|
||||||
|
|
||||||
|
.loop:
|
||||||
|
mov dl, byte [rax]
|
||||||
|
test dl, dl
|
||||||
|
je .done
|
||||||
|
|
||||||
|
; if (*p == '-' || *p == '+') return -1
|
||||||
|
cmp dl, 45 ; '-'
|
||||||
|
je .error
|
||||||
|
cmp dl, 43 ; '+'
|
||||||
|
je .error
|
||||||
|
|
||||||
|
; r10(idx) = *p / 32
|
||||||
|
; rdx(bit) = *p % 32
|
||||||
|
mov r10, [rax]
|
||||||
|
shr r10, 5
|
||||||
|
mov rdx, [rax]
|
||||||
|
and rdx, 31
|
||||||
|
|
||||||
|
; mask = 1 << rdx(bit)
|
||||||
|
mov r11, 1
|
||||||
|
mov cl, dl
|
||||||
|
shl r11, cl
|
||||||
|
|
||||||
|
; if (bits[idx] & mask) return -1
|
||||||
|
mov r9, [rsp + rdx]
|
||||||
|
and r9, r11
|
||||||
|
test r9, r9
|
||||||
|
jne .error
|
||||||
|
|
||||||
|
; bits[idx] |= mask
|
||||||
|
or [rsp + rdx], r11
|
||||||
|
|
||||||
|
; ++p
|
||||||
|
inc rax
|
||||||
|
|
||||||
|
jmp .loop
|
||||||
|
.done:
|
||||||
|
sub rax, qword [rsp + 32]
|
||||||
|
|
||||||
|
.return:
|
||||||
|
add rsp, 40
|
||||||
|
pop rbp
|
||||||
|
ret
|
||||||
|
|
||||||
|
.error:
|
||||||
|
mov rax, -1
|
||||||
|
jmp .return
|
||||||
|
|
||||||
|
; rdi: str
|
||||||
|
; skip whitespace
|
||||||
|
; return :
|
||||||
|
; rax str + x
|
||||||
|
; dl is_signed
|
||||||
|
; rax = 0 if 2 sign
|
||||||
|
find_start:
|
||||||
|
push r12
|
||||||
|
mov r12, rdi
|
||||||
|
.loop:
|
||||||
|
mov dil, byte [r12]
|
||||||
|
call ft_isspace wrt ..plt
|
||||||
|
|
||||||
|
test rax, rax
|
||||||
|
je .done
|
||||||
|
test dil, dil
|
||||||
|
je .done
|
||||||
|
|
||||||
|
inc r12
|
||||||
|
jmp .loop
|
||||||
|
.done:
|
||||||
|
mov rax, r12
|
||||||
|
mov dl, 0
|
||||||
|
|
||||||
|
pop r12
|
||||||
|
|
||||||
|
cmp byte [rax], '-'
|
||||||
|
je .is_signed
|
||||||
|
|
||||||
|
ret
|
||||||
|
.is_signed:
|
||||||
|
inc dl
|
||||||
|
inc rax
|
||||||
|
ret
|
||||||
|
|
||||||
|
; rdi base
|
||||||
|
; rsi char
|
||||||
|
is_in_base:
|
||||||
|
.loop:
|
||||||
|
mov dl, byte [rdi]
|
||||||
|
test dl, dl
|
||||||
|
je .is_not_in
|
||||||
|
|
||||||
|
cmp dl, sil
|
||||||
|
je .is_in
|
||||||
|
|
||||||
|
inc rdi
|
||||||
|
jmp .loop
|
||||||
|
|
||||||
|
.is_in:
|
||||||
|
mov rax, 1
|
||||||
|
ret
|
||||||
|
|
||||||
|
.is_not_in:
|
||||||
|
xor rax, rax
|
||||||
|
ret
|
||||||
|
|
||||||
|
; rdi: base
|
||||||
|
; rsi: char
|
||||||
|
; rdx: baselen
|
||||||
|
|
||||||
|
; int i = 0
|
||||||
|
; while i < baselen
|
||||||
|
; if (c == base[i])
|
||||||
|
; return 1
|
||||||
|
; inc i
|
||||||
|
; return -1
|
||||||
|
|
||||||
|
get_num_from_base:
|
||||||
|
xor rax, rax; rax = i = 0
|
||||||
|
|
||||||
|
.loop:
|
||||||
|
cmp rax, rdx
|
||||||
|
jge .not_found
|
||||||
|
|
||||||
|
mov cl, byte [rdi + rax]
|
||||||
|
cmp cl, sil
|
||||||
|
je .found
|
||||||
|
|
||||||
|
inc rax
|
||||||
|
jmp .loop
|
||||||
|
|
||||||
|
.found:
|
||||||
|
mov rax, 1
|
||||||
|
ret
|
||||||
|
|
||||||
|
.not_found:
|
||||||
|
mov rax, -1
|
||||||
|
ret
|
||||||
|
|
||||||
|
; r12: str
|
||||||
|
; r13: base
|
||||||
|
ft_atoibase:
|
||||||
|
push r12
|
||||||
|
push r13
|
||||||
|
push r14
|
||||||
|
push r15
|
||||||
|
|
||||||
|
mov r12, rdi
|
||||||
|
mov r13, rsi
|
||||||
|
|
||||||
|
; if (check_base(base) <= 0 ) return 0;
|
||||||
|
mov rdi, r13
|
||||||
|
call check_base
|
||||||
|
test rax, rax
|
||||||
|
jle .invalid_base
|
||||||
|
|
||||||
|
; r14 = base_len
|
||||||
|
mov r14, rax
|
||||||
|
|
||||||
|
; str += start + is_signed
|
||||||
|
; rb9 = is_signed
|
||||||
|
mov rdi, r12
|
||||||
|
call find_start
|
||||||
|
mov r12, rax
|
||||||
|
mov r15b, dl
|
||||||
|
|
||||||
|
; r11 = r = 0
|
||||||
|
xor r11, r11
|
||||||
|
.loop:
|
||||||
|
cmp byte [r12], 0
|
||||||
|
je .done
|
||||||
|
|
||||||
|
|
||||||
|
mul r11, r14
|
||||||
|
mov rdi, r13
|
||||||
|
movzx rsi, byte [r12]
|
||||||
|
mov rdx, r14
|
||||||
|
|
||||||
|
push r11
|
||||||
|
call get_num_from_base
|
||||||
|
pop r11
|
||||||
|
cmp rax, rax
|
||||||
|
jl .done
|
||||||
|
|
||||||
|
add r11, rax
|
||||||
|
; r += rax
|
||||||
|
|
||||||
|
inc r12
|
||||||
|
jmp .loop
|
||||||
|
.done:
|
||||||
|
mov rax, r11
|
||||||
|
|
||||||
|
test r9b, r9b
|
||||||
|
je .pos
|
||||||
|
neg rax
|
||||||
|
.pos:
|
||||||
|
|
||||||
|
pop r12
|
||||||
|
pop r13
|
||||||
|
pop r14
|
||||||
|
pop r15
|
||||||
|
ret
|
||||||
|
|
||||||
|
.invalid_base:
|
||||||
|
; errno = EINVAL
|
||||||
|
call __errno_location wrt ..plt
|
||||||
|
mov dword [rax], 22
|
||||||
|
xor rax, rax
|
||||||
|
jmp .done
|
||||||
|
|
||||||
|
.overflow:
|
||||||
|
xor rax, rax ; TODO: LONG_MAX | LONG_MIN
|
||||||
|
jmp .done
|
||||||
Loading…
Add table
Reference in a new issue