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