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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
%ifndef DTOS_INC
%define DTOS_INC
%ifndef MONAD_INC
%include "monad.inc"
%endif
;; TODO: Thread safety, allocate the write buffer instead of a global state incase it is interrupted and rewritten
section .data
_NUMERALS db "0123456789ABCDEF"
_DATA_BYTE_BUFFER times 63 db "0"
_FIRST_DIGIT db "0", 0x0A, 0
m_make DTOS_RESULT, _DATA_BYTE_BUFFER
%macro dtomz_h 1
%if "%1" != "%rax"
mov rax, %1
%endif
mov rcx, 16
call data_to_zstring
%endm
%macro dtomz_d 1
%if "%1" != "%rax"
mov rax, %1
%endif
mov rcx, 10
call data_to_zstring
%endm
%macro dtomz_o 1
%if "%1" != "%rax"
mov rax, %1
%endif
mov rcx, 8
call data_to_zstring
%endm
%macro dtomz_b 1
%if "%1" != "%rax"
mov rax, %1
%endif
mov rcx, 2
call data_to_zstring
%endm
section .text
clear_data_zstring:
push rbp
mov rbp, rsp
push rdi
cld
lea rdi, [rel _DATA_BYTE_BUFFER]
mov al, "0"
mov rcx, 64
rep stosb
std
pop rdi
mov rsp, rbp
pop rbp
ret
data_to_zstring:
;; rax: Value
;; rcx: Base
push rbp
mov rbp, rsp
;;
push rax
push rcx
call clear_data_zstring
pop rcx
pop rax
cmp rcx, 16
ja .err_exit
cmp rcx, 2
jb .err_exit
std
;; Preserve Caller-saved registers
push rsi
push rdi
;; Initially include newline character
lea rdi, [rel _FIRST_DIGIT]
.loop:
;; Get lowest digit
xor rdx, rdx
div rcx
;; Set the numeral
lea rsi, [rel _NUMERALS]
add rsi, rdx
movsb
cmp rax, 0
jne .loop
mov rax, rdi
inc rax
cld
;; Recover Registers
pop rdi
pop rsi
m_return rel m_DTOS_RESULT, rax
jmp .exit
.err_exit:
m_Nothing rel m_DTOS_RESULT
.exit:
lea rax, [rel m_DTOS_RESULT]
;;
mov rsp, rbp
pop rbp
ret
;; Monadic functions (m_bind d2zs_m?)
;; data_to_zstring_m?
;; rax -> M (d2zs_? rax)
data_to_zstring_mh:
mov rcx, 16
call data_to_zstring
ret
data_to_zstring_md:
mov rcx, 10
call data_to_zstring
ret
data_to_zstring_mo:
mov rcx, 8
call data_to_zstring
ret
data_to_zstring_mb:
mov rcx, 2
call data_to_zstring
ret
%endif
|