summaryrefslogtreecommitdiff
path: root/PGU/CHAP10/int2str.s
diff options
context:
space:
mode:
authorCarlos Maiolino <[email protected]>2025-07-10 22:55:07 +0200
committerCarlos Maiolino <[email protected]>2025-07-10 22:56:55 +0200
commitd98f46ce647846b0aa30b2e16a30fd4e152a1bf5 (patch)
tree267474fcc77cf20b428f6f4c7f768ca09f4cfe0e /PGU/CHAP10/int2str.s
parent869e68986aa8f69af6e7842260a68d1e5c6f796f (diff)
Add new code
Signed-off-by: Carlos Maiolino <[email protected]>
Diffstat (limited to 'PGU/CHAP10/int2str.s')
-rw-r--r--PGU/CHAP10/int2str.s86
1 files changed, 86 insertions, 0 deletions
diff --git a/PGU/CHAP10/int2str.s b/PGU/CHAP10/int2str.s
new file mode 100644
index 0000000..6ea5178
--- /dev/null
+++ b/PGU/CHAP10/int2str.s
@@ -0,0 +1,86 @@
+# integer2string
+#
+# Convert an int number to a decima string for display
+#
+# Receives a buffer large enough to hold the largest possible numberr
+# and an integer to convert
+#
+# %rcx hold the count of characters processed
+# %rax holds the current value
+# %rdi hold the base (10)
+
+.equ ST_VALUE, 16
+.equ ST_BUFFER, 24
+
+.globl integer2string
+.type integer2string, @function
+
+integer2string:
+
+ # Default function setup
+ pushq %rbp
+ movq %rsp, %rbp
+
+ movq $0, %rcx # Init char count
+ movq ST_VALUE(%rbp), %rax # Retrieve value from stack
+
+ # The divisor must be in a register or memory location
+ movq $10, %rdi
+
+ conversion_loop:
+ # Division is actually performed on the combined
+ # %rdx:%rax register, so first, clear out %rdx
+ movq $0, %rdx
+
+ # Divide %rdx:%rax (which are implied) by 10
+ # Store the quotient in %rax and the remainder in
+ # %rdx (both which are implied)
+ divq %rdi
+
+ # Quotient is in the right place. %rdx has the remainder
+ # which now needs to be converted into a number. So, %rdx has a
+ # number that is 0 through 9. We'll use it as an 'index' on the
+ # ASCII table starting from char '0'.
+ addq $'0', %rdx # Get our number's index from ASCII
+ # table, starting from '0'.
+
+ # Push this value into the stack. When we are done, we can just
+ # pop them off one-by-one, and they will be in the right order.
+ # NOTE: We are pushing the whole register, but we only need the
+ # byte in %dl (The last byte of the %rdx register) for the
+ # character.
+ pushq %rdx
+
+ incq %rcx # Increment digit count
+
+ cmpq $0, %rax # Have we reached the end of the calculation?
+ je end_conversion_loop
+
+ # %rax has its new value
+ jmp conversion_loop
+
+ end_conversion_loop:
+ # The string is now on the stack, if we pop it off a char at a
+ # time, we can copy it into the buffer and we are done.
+
+ movq ST_BUFFER(%rbp), %rdx # Move buffer address to %rdx
+
+ copy_reversing_loop:
+ popq %rax
+ movb %al, (%rdx)
+ decq %rcx # Once we reach 0 we are finished
+ incq %rdx # Point to the next byte
+
+ cmpq $0, %rcx # Check if we are finished
+ je end_copy_reversing_loop
+
+ jmp copy_reversing_loop
+
+ end_copy_reversing_loop:
+ movb $0, (%rdx)
+
+ movq %rbp, %rsp
+ popq %rbp
+ ret
+
+# end of integer2string