; 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