aboutsummaryrefslogtreecommitdiff
path: root/dtos.inc
blob: 56bd0c67552d8ba6603b7f13145c7e89b58cb79f (plain)
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