diff options
Diffstat (limited to '04-Largest-Palindrome-Product/asm')
-rw-r--r-- | 04-Largest-Palindrome-Product/asm/Makefile | 6 | ||||
-rwxr-xr-x | 04-Largest-Palindrome-Product/asm/palindrome | bin | 0 -> 17736 bytes | |||
-rw-r--r-- | 04-Largest-Palindrome-Product/asm/palindrome.asm | 83 | ||||
-rw-r--r-- | 04-Largest-Palindrome-Product/asm/palindrome.o | bin | 0 -> 3424 bytes |
4 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 Binary files differnew file mode 100755 index 0000000..3f75c67 --- /dev/null +++ b/04-Largest-Palindrome-Product/asm/palindrome 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 Binary files differnew file mode 100644 index 0000000..6f1d9da --- /dev/null +++ b/04-Largest-Palindrome-Product/asm/palindrome.o |