-
Notifications
You must be signed in to change notification settings - Fork 0
/
014.asm
65 lines (55 loc) · 2.05 KB
/
014.asm
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
section .data
msg db "%d", 10, 0 ;return string for printf (just the result)
cache times 1000000 dd 0 ;cache for already computed chain lengths
section .text
extern printf
global main
main:
mov ebx, 1 ;starting number
xor r9d, r9d ;max length
xor r10d, r10d ;number with max length
collatz:
inc ebx ;next number
cmp ebx, 1000000 ;check if we reached 1000000
je print ;if yes, print result
mov rax, rbx ;copy number to rax
xor r8d, r8d ;reset chain length
even:
cmp rax, 1000000 ;check if current number < 1000000
jge continue ;if not, jump to continue
mov edi, [cache + 4 * eax] ;if yes, check cache @ current number
test edi, edi
jnz updatemax ;if > 0 break and jump to updatemax
continue:
test eax, 1 ;check if curent number is odd
jnz odd ;if yes, jump to odd
shr rax, 1 ;else half
inc r8d ;increase chain legth
jmp even ;back
odd:
cmp rax, 1 ;check if we reached 1
je updatemax ;if yes, jump to updatemax
mov rcx, rax ;compute 3 * n + 1
shl rax, 1
add rax, rcx
inc rax
inc r8d ;increase chain length
jmp even ;back to even
updatemax:
add r8d, [cache + 4 * eax] ;add cache @ current number to length
mov [cache + 4 * ebx], r8d ;update cache
cmp r8d, r9d ;check if current length > max
cmovg r9d, r8d ;if yes update max length
cmovg r10d, ebx ;update number of max length
jmp collatz
print: ;printing routine, differs slightly from OS to OS
push rbp
mov edi, msg
mov esi, r10d
call printf
pop rbp
exit: ;exit routine, dito
mov eax, 1
xor edi, edi
syscall
section .note.GNU-stack ;just for gcc