aboutsummaryrefslogtreecommitdiffstats
path: root/04-Largest-Palindrome-Product/asm/palindrome.asm
diff options
context:
space:
mode:
Diffstat (limited to '04-Largest-Palindrome-Product/asm/palindrome.asm')
-rw-r--r--04-Largest-Palindrome-Product/asm/palindrome.asm83
1 files changed, 83 insertions, 0 deletions
diff --git a/04-Largest-Palindrome-Product/asm/palindrome.asm b/04-Largest-Palindrome-Product/asm/palindrome.asm
new file mode 100644
index 0000000..03cd724
--- /dev/null
+++ b/04-Largest-Palindrome-Product/asm/palindrome.asm
@@ -0,0 +1,83 @@
+; Find the largest palindrome made from the product of two 3-digit numbers.
+
+extern printf
+SECTION .data
+flag: db "%d",10,0 ; "%d\n\0"
+
+SECTION .text
+ global main
+ global is_palindrome
+
+is_palindrome:
+; check if the product in rax is a palindrome
+
+ push rax ; save the value
+ xor r14, r14 ; using this as a string length counter
+.div: xor rdx, rdx ; clear operand for div
+ div r12 ; rdx:rax / 10
+ add rdx, 0x30 ; digit is in remainder, add ascii 0
+ push rdx
+ inc r14
+ cmp rax, 0
+ jnz .div
+
+; Cheating a bit here. Highest product of two 3 digit numbers will
+; not exceed 6 digits. We assume only three comparisons need to made
+; 5 digit numbers are excluded outright
+
+ cmp r14, 6
+ jne main.nexti ; return
+ mov rax, [rsp]
+ mov rdx, [rbp-0x18] ; at this point, original rbp, ret and rax are
+ cmp rax, rdx ; on the stack, so skip three qwords (64bits)
+ jne main.nexti
+ mov rax, [rsp+8]
+ mov rdx, [rbp-0x20]
+ cmp rax, rdx
+ jne main.nexti
+ mov rax, [rsp+16]
+ mov rdx, [rbp-0x28]
+ cmp rax, rdx
+ jne main.nexti
+ ; if you made it here, rax is a palindrome!
+ mov rsp, rbp ; reset stack back to the first variable
+ sub rsp, 16 ; first 8 bytes is the return call
+ pop rax
+ ret
+
+main:
+ push rbp ; set up stack
+ mov rbp, rsp
+ mov r11, 0x3E7 ; j=999
+ mov r12, 0xA ; for division testing later
+ xor r13, r13 ; current max palindrome (0)
+; check products for three digit numbers (starting with highest)
+.loopj mov rcx, 0x3E7 ; setup counter two (i=999)
+
+.loopi xor rdx, rdx ; clear operand for mul
+ mov rax, r11 ; operand for mul
+ mul rcx ; rdx:rax = rax * rcx (j * i)
+ ; hint this won't overflow
+ call is_palindrome
+ ; if you made it here, rax is a palindrome!
+ cmp rax, r13 ; if rax is not bigger than the current max
+ jl .nexti ; next loop
+ mov r13, rax ; otherwise, update value
+
+.nexti: mov rsp, rbp ; reset stack (if needed)
+ loopnz .loopi ; i = 0, decrement j and restart
+
+ dec r11 ; j--
+ jnz .loopj
+
+.print mov rdi, flag ; arg 1 (format)
+ mov rsi, r13 ; arg 2
+ mov rax, 0 ; no xmm registers
+ call printf wrt ..plt
+
+ mov rsp, rbp ; reset to the top of the stack
+ pop rbp
+
+ mov rax, 0
+ ret
+