-
Notifications
You must be signed in to change notification settings - Fork 0
/
021.asm
71 lines (60 loc) · 2.21 KB
/
021.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
66
67
68
69
70
71
section .data
msg db "%d", 10, 0 ;return string for printf (just the result)
section .text
extern printf
global main
main:
mov ecx, 1 ;starting number
xor r9d, r9d ;sum
findamicables:
inc ecx ;next number
cmp ecx, 10000 ;check if we are under 10000
je print ;if not, print result
call divsum ;calculate sum of divisors
cmp ecx, r8d ;check if sum = number (i.e. a perfect number)
je findamicables ;if yes, skip that
push rcx ;put current number on the stack
mov ecx, r8d ;put divsum in ebx
call divsum ;calculate divsum of that
pop rcx ;get number back from the stack
cmp ecx, r8d ;check if n = divsum of divsum n (i.e. amicables)
jne findamicables ;if not, try next number
add r9d, ecx ;else add number to sum
jmp findamicables ;continue with next number
divsum:
mov ebx, 1 ;reset divisor
xor r8d, r8d ;reset sum of divisors
divide:
inc ebx ;increase divisor (start with 2)
mov eax, ebx ;put divisor in eax
mul ebx ;square
cmp eax, ecx ;check if suqare is > number
jg finished ;if yes, we are finished
mov eax, ecx ;else put number in eax
xor edx, edx ;reset remainder
div ebx ;divide by current divisor
test edx, edx ;check if remainder = 0
jnz divide ;if not, try next divisor
cmp eax, ebx ;else check if result is equal to divisor
je add1 ;if yes, just add the divisor
add2:
add r8d, ebx ;else add divisor and number / divisor
add r8d, eax
jmp divide
add1:
add r8d, ebx
jmp divide
finished:
inc r8d ;add 1, as this is always a divisor
ret
print: ;printing routine, differs slightly from OS to OS
push rbp
mov edi, msg
mov esi, r9d
call printf
pop rbp
exit: ;exit routine, dito
mov eax, 1
xor edi, edi
syscall
section .note.GNU-stack ;just for gcc