159 lines
2.9 KiB
NASM
159 lines
2.9 KiB
NASM
include errno
|
|
|
|
; Convert integer to string
|
|
; Arguments:
|
|
; r1 - Integer
|
|
; r2 - Start of buffer
|
|
; r3 - Buffer length
|
|
; r4 - Base (2, 8, 10, or 16)
|
|
; Result:
|
|
; none
|
|
; Clobbers:
|
|
; Based on specialization
|
|
pub auto:
|
|
cmp r4, 2
|
|
je bin
|
|
cmp r4, 8
|
|
je oct
|
|
cmp r4, 16
|
|
je hex
|
|
mov flags, errno.INTTOSTR_BAD_BASE
|
|
jmp r13
|
|
|
|
; The output buffer is too small for this integer
|
|
badbuffer:
|
|
mov flags, errno.INTTOSTR_BAD_BUFFER
|
|
jmp r13
|
|
|
|
; All digits have been output. Null terminate and exit.
|
|
done:
|
|
store_8 [r2], zr
|
|
mov flags, errno.OK
|
|
jmp r13
|
|
|
|
; Convert integer to binary string
|
|
; Arguments:
|
|
; r1 - Integer
|
|
; r2 - Start of buffer
|
|
; r3 - Buffer length
|
|
; Result:
|
|
; none
|
|
; Clobbers:
|
|
; flags
|
|
; r4 - counter
|
|
; r5 - character
|
|
pub bin:
|
|
mov r4, 31
|
|
cmp r2, 2
|
|
jl badbuffer
|
|
|
|
bin_find_one:
|
|
lsr r5, r1, r4 ; Select bit and advance counter
|
|
and r5, r5, 1
|
|
sub r4, r4, 1
|
|
|
|
cmp r4, 0 ; Start printing if last bit ...
|
|
jl bin_print
|
|
cmp r5, zr ; .. or if nonzero
|
|
je bin_find_one
|
|
|
|
add flags, r4, 3 ; Check buffer size
|
|
cmp flags, r3
|
|
ja badbuffer
|
|
|
|
bin_print:
|
|
add r5, r5, 0x30 ; '0' ; Add digit to buffer
|
|
store_8 [r2], r5
|
|
add r2, r2, 1
|
|
cmp r4, 0 ; Done if last bit
|
|
jl done
|
|
lsr r5, r1, r4 ; Select bit and advance counter
|
|
and r5, r5, 1
|
|
sub r4, r4, 1
|
|
jmp bin_print
|
|
|
|
; Convert integer to octal string
|
|
; Arguments:
|
|
; r1 - Integer
|
|
; r2 - Start of buffer
|
|
; r3 - Buffer length
|
|
; Result:
|
|
; none
|
|
; Clobbers:
|
|
; flags
|
|
; r4 - input counter
|
|
; r5 - character
|
|
; r6 - output size counter
|
|
pub oct:
|
|
mov r4, 30
|
|
mov r6, 12
|
|
|
|
oct_find_one:
|
|
lsr r5, r1, r4 ; Select bit and advance counter
|
|
and r5, r5, 7
|
|
sub r4, r4, 3
|
|
sub r6, r6, 1
|
|
|
|
cmp r4, 0 ; Start printing if last bit ...
|
|
jl oct_print
|
|
cmp r5, zr ; .. or if nonzero
|
|
je oct_find_one
|
|
|
|
cmp r6, r3 ; Check buffer size
|
|
ja badbuffer
|
|
|
|
oct_print:
|
|
add r5, r5, 0x30 ; '0' ; Add digit to buffer
|
|
store_8 [r2], r5
|
|
add r2, r2, 1
|
|
cmp r4, 0 ; Done if last bit
|
|
jl done
|
|
lsr r5, r1, r4 ; Select bit and advance counter
|
|
and r5, r5, 7
|
|
sub r4, r4, 3
|
|
jmp oct_print
|
|
|
|
; Convert integer to hexadecimal string
|
|
; Arguments:
|
|
; r1 - Integer
|
|
; r2 - Start of buffer
|
|
; r3 - Buffer length
|
|
; Result:
|
|
; none
|
|
; Clobbers:
|
|
; flags
|
|
; r4 - input counter
|
|
; r5 - character
|
|
pub hex:
|
|
mov r4, 28
|
|
|
|
hex_find_one:
|
|
lsr r5, r1, r4 ; Select bit and advance counter
|
|
and r5, r5, 0xF
|
|
sub r4, r4, 4
|
|
|
|
cmp r4, 0 ; Start printing if last bit ...
|
|
jl hex_print
|
|
cmp r5, zr ; .. or if nonzero
|
|
je hex_find_one
|
|
|
|
lsr flags, r5, 2 ; Check buffer size
|
|
add flags, flags, 3
|
|
cmp flags, r3
|
|
ja badbuffer
|
|
|
|
hex_print:
|
|
add r5, r5, 0x30 ; '0' ; Add digit to buffer
|
|
cmp r5, 0x39 ; '9'
|
|
jle hex_no_letter
|
|
add r5, r5, 0x07 ; 'A' - '0' - 10
|
|
hex_no_letter:
|
|
store_8 [r2], r5
|
|
add r2, r2, 1
|
|
cmp r4, 0 ; Done if last bit
|
|
jl done
|
|
lsr r5, r1, r4 ; Select bit and advance counter
|
|
and r5, r5, 0xF
|
|
sub r4, r4, 4
|
|
jmp hex_print
|