aboutsummaryrefslogtreecommitdiffstats
path: root/04-Largest-Palindrome-Product
diff options
context:
space:
mode:
authormjfernez <mjfernez@gmail.com>2021-10-12 20:18:28 -0400
committermjfernez <mjfernez@gmail.com>2021-10-12 20:18:28 -0400
commit3cf128d6da667d00bb5bb659413ea55a98a02aff (patch)
tree12eb90997dfa63d65fe6da714626271272342320 /04-Largest-Palindrome-Product
parent009ce017d99a8deb2089438381c273e8f3ea3b67 (diff)
downloadProject_Euler_Solutions-3cf128d6da667d00bb5bb659413ea55a98a02aff.tar.gz
Added description. x86 solutions for some problemsHEADmaster
Diffstat (limited to '04-Largest-Palindrome-Product')
-rw-r--r--04-Largest-Palindrome-Product/asm/Makefile6
-rwxr-xr-x04-Largest-Palindrome-Product/asm/palindromebin0 -> 17736 bytes
-rw-r--r--04-Largest-Palindrome-Product/asm/palindrome.asm83
-rw-r--r--04-Largest-Palindrome-Product/asm/palindrome.obin0 -> 3424 bytes
-rwxr-xr-x[-rw-r--r--]04-Largest-Palindrome-Product/palindromebin16824 -> 16824 bytes
5 files changed, 89 insertions, 0 deletions
diff --git a/04-Largest-Palindrome-Product/asm/Makefile b/04-Largest-Palindrome-Product/asm/Makefile
new file mode 100644
index 0000000..53b33b2
--- /dev/null
+++ b/04-Largest-Palindrome-Product/asm/Makefile
@@ -0,0 +1,6 @@
+palindrome: palindrome.o
+ gcc palindrome.o -o palindrome
+palindrome.o: palindrome.asm
+ nasm -w+all -f elf64 -g -F stabs palindrome.asm
+clean:
+ rm -f palindrome palindrome.o
diff --git a/04-Largest-Palindrome-Product/asm/palindrome b/04-Largest-Palindrome-Product/asm/palindrome
new file mode 100755
index 0000000..3f75c67
--- /dev/null
+++ b/04-Largest-Palindrome-Product/asm/palindrome
Binary files differ
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
+
diff --git a/04-Largest-Palindrome-Product/asm/palindrome.o b/04-Largest-Palindrome-Product/asm/palindrome.o
new file mode 100644
index 0000000..6f1d9da
--- /dev/null
+++ b/04-Largest-Palindrome-Product/asm/palindrome.o
Binary files differ
diff --git a/04-Largest-Palindrome-Product/palindrome b/04-Largest-Palindrome-Product/palindrome
index f4d607f..f4d607f 100644..100755
--- a/04-Largest-Palindrome-Product/palindrome
+++ b/04-Largest-Palindrome-Product/palindrome
Binary files differ