aboutsummaryrefslogtreecommitdiff
path: root/src/lib/int2str.s
diff options
context:
space:
mode:
authormithe24 <mithe24@student.sdu.dk>2025-10-26 15:38:43 +0100
committermithe24 <mithe24@student.sdu.dk>2025-10-29 13:49:57 +0100
commit2e39f481369d708cf2c723136c3bf4c765d6c994 (patch)
tree0e5d7b8588ad8d31875725cfabbc17d876037038 /src/lib/int2str.s
parent88d4c92a5a757ed4ee88373e9ae53bfe27041e7f (diff)
downloadsorter-2e39f481369d708cf2c723136c3bf4c765d6c994.tar.gz
sorter-2e39f481369d708cf2c723136c3bf4c765d6c994.zip
fix(printing & int2str): Better printing and int to string func
Diffstat (limited to 'src/lib/int2str.s')
-rw-r--r--src/lib/int2str.s83
1 files changed, 83 insertions, 0 deletions
diff --git a/src/lib/int2str.s b/src/lib/int2str.s
new file mode 100644
index 0000000..82a2aaa
--- /dev/null
+++ b/src/lib/int2str.s
@@ -0,0 +1,83 @@
+# --------------------------------------------
+# FUNCTION: int2str
+# PURPOSE : Convert a 64 bit integer into ascii
+# into ASCII encoding
+# INPUTS : rdi = 64 bit integer
+# rsi = address of buffer
+# OUTPUTS : rax = address of string (points into the provided buffer)
+# rdx = length of string
+# CLOBBERS:
+# --------------------------------------------
+.section .text
+.globl int2str
+.type int2str, @function
+int2str:
+ pushq %rbx # save callee-saved register
+
+ movq %rdi, %rax # integer to convert
+ movq %rsi, %rbx # buffer base
+ movq %rsi, %r9 # save original buffer
+ leaq 19(%rbx), %r8 # pointer to last char position
+ movq $10, %rcx # divisor
+ xorq %r10, %r10 # sign flag (0 = positive)
+
+ # handle sign
+ testq %rax, %rax
+ jns .convert
+ negq %rax # if the number negative we negate it and
+ movq $1, %r10 # set sign flag
+
+.convert:
+ testq %rax, %rax
+ jnz .loop # check if the number is 0
+
+ # if the number is 0, we just set the char to '0', and length to 0.
+ movb $'0', (%r8)
+ movq %r8, %rax
+ movq $1, %rdx
+ jmp .shift_left # shift the result leftmust
+
+.loop:
+ xorq %rdx, %rdx # clear rdx before division
+ divq %rcx # divide rdx:rax by 10
+ addb $'0', %dl # add ASCII base
+ movb %dl, (%r8) # move digit into buffer
+ decq %r8 # decrement pointer
+ testq %rax, %rax # while quotient is not 0, loop
+ jnz .loop
+
+ incq %r8 # move back to first digit
+
+ # add '-' if negative
+ testq %r10, %r10
+ jns .calc_len
+ decq %r8
+ movb $'-', (%r8)
+
+.calc_len: # count length of the string
+ movq %r8, %rax # string start
+ leaq 20(%r9), %rdx # end of buffer
+ subq %rax, %rdx # string length
+
+.shift_left:
+ # shift string to leftmost in buffer if not already there
+ cmpq %rax, %r9
+ je .done # already leftmost
+ movq %rdx, %rcx # rcx = length of string
+ movq %rax, %rsi # rsi = source :: start of string
+ movq %r9, %rdi # rdi = destination :: original buff start
+ rep movsb # copy string left
+ # Found this online. It's a way to copy down values in memoery.
+ # movbs = Move String Byte..
+ # It copies 1 byte from memoery to memoery and
+ # incrementing destination and incrementing source.
+ # Source :: %rsi
+ # Dest :: %rdi
+ # rep = repeat wow.
+ # It's a prefix that repeats an isntructution rcx times
+ # https://stackoverflow.com/questions/27804852/assembly-rep-movs-mechanism
+ movq %r9, %rax # return pointer to start
+
+.done:
+ popq %rbx
+ ret