radix, negative numbers
This commit is contained in:
parent
15c2aea16a
commit
f60573c06f
|
|
@ -5,24 +5,32 @@ global int_to_str2
|
||||||
;; rdi: input integer
|
;; rdi: input integer
|
||||||
;; rsi: pointer to output buffer (at least 21 bytes)
|
;; rsi: pointer to output buffer (at least 21 bytes)
|
||||||
;; rdx: length of buffer
|
;; rdx: length of buffer
|
||||||
;; fn int_to_str2(value: i64, buffer: *mut u8, len: usize) -> (*mut u8, usize)
|
;; cl: radix
|
||||||
|
;; fn int_to_str2(value: i64, buffer: *mut u8, len: usize, radix: u8) -> (*mut u8, usize)
|
||||||
int_to_str2:
|
int_to_str2:
|
||||||
push rbp
|
push rbp
|
||||||
mov rbp, rsp
|
mov rbp, rsp
|
||||||
push r12
|
push r12
|
||||||
push r13
|
push r13
|
||||||
xor r12, r12 ; r12 = index
|
sub rsp, 0x20
|
||||||
mov r13, rdx ; r13 = buffer length
|
mov [rsp], rdi ; save value
|
||||||
|
mov [rsp + 8], rdx ; save length
|
||||||
|
mov [rsp + 16], rcx ; save radix
|
||||||
|
|
||||||
test r13, r13
|
xor r12, r12 ; r12 = index
|
||||||
|
|
||||||
|
test rdx, rdx
|
||||||
jz .epilogue ; if length is 0, return
|
jz .epilogue ; if length is 0, return
|
||||||
|
|
||||||
|
xor r13, r13
|
||||||
mov rcx, rdi
|
mov rcx, rdi
|
||||||
sar rcx, 63 ; check sign
|
sar rcx, 63 ; check sign
|
||||||
cmp rcx, 0
|
cmp rcx, 0
|
||||||
je .convert
|
je .convert
|
||||||
.negative:
|
.negative:
|
||||||
mov byte [rsi], '-' ; write minus sign
|
mov byte [rsi], '-' ; write minus sign
|
||||||
|
neg rdi
|
||||||
|
inc r13
|
||||||
inc r12
|
inc r12
|
||||||
|
|
||||||
.convert:
|
.convert:
|
||||||
|
|
@ -32,14 +40,22 @@ int_to_str2:
|
||||||
jmp .epilogue
|
jmp .epilogue
|
||||||
|
|
||||||
.convert_loop:
|
.convert_loop:
|
||||||
cmp r12, r13
|
mov rax, [rsp + 8] ; buffer length
|
||||||
|
cmp r12, rax
|
||||||
jge .epilogue ; prevent buffer overflow
|
jge .epilogue ; prevent buffer overflow
|
||||||
|
|
||||||
mov rax, rdi
|
mov rax, rdi
|
||||||
xor rdx, rdx
|
xor rdx, rdx
|
||||||
mov rcx, 10 ; base 10
|
mov rcx, [rsp + 16] ; base 10
|
||||||
div rcx ; rax = rdi / 10, rdx = rdi % 10
|
mov cl, cl
|
||||||
|
div rcx ; rax = rdi / radix, rdx = rdi % radix
|
||||||
|
cmp rdx, 10
|
||||||
|
jl .decimal
|
||||||
|
add rdx, 'a' - 10 ; convert to 'a'-'f'
|
||||||
|
jmp .phi
|
||||||
|
.decimal:
|
||||||
add rdx, '0' ; convert digit to ASCII
|
add rdx, '0' ; convert digit to ASCII
|
||||||
|
.phi:
|
||||||
mov byte [rsi + r12], dl
|
mov byte [rsi + r12], dl
|
||||||
inc r12
|
inc r12
|
||||||
mov rdi, rax
|
mov rdi, rax
|
||||||
|
|
@ -47,7 +63,6 @@ int_to_str2:
|
||||||
jnz .convert_loop
|
jnz .convert_loop
|
||||||
|
|
||||||
; Reverse the digits
|
; Reverse the digits
|
||||||
xor r13, r13
|
|
||||||
mov rdx, r12
|
mov rdx, r12
|
||||||
dec r12 ; last digit index
|
dec r12 ; last digit index
|
||||||
.reverse_loop:
|
.reverse_loop:
|
||||||
|
|
@ -63,6 +78,7 @@ int_to_str2:
|
||||||
.done_reverse:
|
.done_reverse:
|
||||||
mov rax, rsi
|
mov rax, rsi
|
||||||
.epilogue:
|
.epilogue:
|
||||||
|
add rsp, 0x20
|
||||||
pop r13
|
pop r13
|
||||||
pop r12
|
pop r12
|
||||||
pop rbp
|
pop rbp
|
||||||
|
|
|
||||||
|
|
@ -19,16 +19,37 @@ impl FFISlice {
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe extern "C" {
|
unsafe extern "C" {
|
||||||
unsafe fn int_to_str2(value: usize, buffer: *mut u8, buffer_len: usize) -> FFISlice;
|
unsafe fn int_to_str2(value: isize, buffer: *mut u8, buffer_len: usize, radix: u8) -> FFISlice;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let value = 1234567890usize;
|
let value = 1234567890isize;
|
||||||
let mut buffer = [0u8; 32];
|
let mut buffer = [0u8; 32];
|
||||||
unsafe {
|
unsafe {
|
||||||
let slice = int_to_str2(value, buffer.as_mut_ptr(), buffer.len());
|
let slice = int_to_str2(value, buffer.as_mut_ptr(), buffer.len(), 10);
|
||||||
let s = slice.as_str();
|
let s = slice.as_str();
|
||||||
println!("Integer: {}, String: {}", value, s);
|
println!("Integer: {}, String: {}", value, s);
|
||||||
assert_eq!(s, value.to_string());
|
assert_eq!(s, format!("{value}"));
|
||||||
|
|
||||||
|
let slice = int_to_str2(0 - value, buffer.as_mut_ptr(), buffer.len(), 10);
|
||||||
|
let s = slice.as_str();
|
||||||
|
println!("Integer: {}, String: {}", 0 - value, s);
|
||||||
|
assert_eq!(s, format!("{}", 0 - value));
|
||||||
|
|
||||||
|
let slice = int_to_str2(value, buffer.as_mut_ptr(), buffer.len(), 16);
|
||||||
|
let s = slice.as_str();
|
||||||
|
println!("Integer: {:x}, String: {}", value, s);
|
||||||
|
assert_eq!(s, format!("{value:x}"));
|
||||||
|
|
||||||
|
let slice = int_to_str2(value, buffer.as_mut_ptr(), buffer.len(), 8);
|
||||||
|
let s = slice.as_str();
|
||||||
|
println!("Integer: {:o}, String: {}", value, s);
|
||||||
|
assert_eq!(s, format!("{value:o}"));
|
||||||
|
|
||||||
|
let value = 235isize;
|
||||||
|
let slice = int_to_str2(value, buffer.as_mut_ptr(), buffer.len(), 2);
|
||||||
|
let s = slice.as_str();
|
||||||
|
println!("Integer: {:b}, String: {}", value, s);
|
||||||
|
assert_eq!(s, format!("{value:b}"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue