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
|
# --------------------------------------------
# FUNCTION: tub2tsv
# PURPOSE : take a buffer of coordinates
# and print each coordinate on a line
# INPUTS : rdi = pointer to buffer,
# rsi = number of coordinates
# OUTPUTS : rax = address to string of tab seperated values
# rdx = number of bytes
# CLOBBERS:
# --------------------------------------------
.section .text
.globl tub2tsv
.type tub2tsv, @function
tub2tsv:
# save callee-saved registers
pushq %r12
pushq %r13
pushq %r14
pushq %r15
pushq %rbx
movq %rdi, %r12 # r12 = address to array of coordinates
movq %rsi, %r13 # r13 = count of coordinates
# allocate memory based on number of coordinates and max integer size
# maybe allocate in chunks might be better, as to waste less memory
movq %rsi, %rdi
imulq $42, %rdi # 20 bytes for each coordindate + tab
incq %rdi # +1 byte for null terminator
call allocate
movq %rax, %r14 # r14 = output buffer start
movq %rax, %r15 # r15 = current write pos
xorq %rbx, %rbx # loop counter
.tub2tsv_loop:
cmpq %r13, %rbx # if loop counter >= count of coordinates
jge .tub2tsv_exit # done
# get addrss to current tuple
movq (%r12, %rbx, 8), %rdi # rdi = array[loop counter]
pushq %rdi # save pointer to current tuple
# convert first integer to ASCII
movq (%rdi), %rdi # rdi = first int
movq %r15, %rsi # rsi = current write pos
call int2str # rax = string start, rdx = length
addq %rdx, %r15 # advance write pos with num bytes written
# write tab
movb $'\t', (%r15)
incq %r15
# convert second integer to ASCII
popq %rdi # restore pointer to tuple
movq 8(%rdi), %rdi # rdi = second int
movq %r15, %rsi # rsi = current write pos
call int2str # rax = string start, rdx = length
addq %rdx, %r15 # advance write pos with num bytes written
# write newline
movb $'\n', (%r15)
incq %r15
incq %rbx
jmp .tub2tsv_loop
.tub2tsv_exit:
# add null terminator
movb $0, (%r15)
# move address to output register
movq %r14, %rax
# return length in rdx
movq %r15, %rdx
subq %r14, %rdx
# restore callee-saved registers
popq %rbx
popq %r15
popq %r14
popq %r13
popq %r12
ret
|