1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
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
|