Skip to content

Commit 41ce2cc

Browse files
committed
Update
1 parent f5e6c8d commit 41ce2cc

File tree

1 file changed

+103
-42
lines changed

1 file changed

+103
-42
lines changed

086.asm

+103-42
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,108 @@
1-
section .data
2-
msg db "%d", 10, 0 ;return string for printf (just the result)
3-
4-
section .text
5-
extern printf
6-
global main
7-
8-
main:
9-
xor ebx, ebx ;r in Dickson's method
10-
xor r10d, r10d ;cuboids
11-
12-
next:
13-
add ebx, 2 ;the next even r (odd values not allowed)
14-
mov eax, ebx ;put number in eax for multiplication
15-
mul ebx ;square
16-
shr eax, 1 ;half
17-
mov ecx, eax ;put r^2 / 2 in ecx
18-
xor edi, edi ;for divisors of r^2 / 2
19-
20-
triplets:
21-
inc edi ;next divisor candidate
22-
mov eax, edi ;candidate in eax
23-
mul edi ;square
24-
cmp eax, ecx ;check if square of candidate is less than r^2 / 2
25-
jg next ;if not, go to next higher r
26-
xor edx, edx ;prepare remainder
27-
mov eax, ecx ;r^2 / 2 in eax for division
28-
div edi ;divide by current divisor
29-
test edx, edx ;check if remainder is zero
30-
jnz triplets ;if not, continue with next divisor
31-
inc r10d
32-
cmp r10d, 1975
33-
jl triplets
34-
35-
print: ;printing routine, differs slightly from OS to OS
36-
push rbp
37-
mov edi, msg
1+
format ELF64 executable 9
2+
3+
segment readable writable
4+
result: times 10 db 0 ;empty string for printing the result later
5+
db 10, 0
6+
7+
segment readable executable
8+
entry start
9+
10+
start:
11+
mov eax, 1 ;length
12+
xor ecx, ecx ;counter
13+
14+
next_l:
15+
cmp ecx, 1000000 ;count > 1e6?
16+
jg finished ;if yes, we are finished
17+
inc eax ;next length
18+
mov edx, eax ;in edx
19+
shl edx, 1 ;2 * l as limit of next loop
20+
mov ebx, 3 ;init width + height
21+
22+
next_wh:
23+
mov edi, eax
24+
imul edi, eax ;l^2
3825
mov esi, ebx
39-
call printf
40-
pop rbp
26+
imul esi, ebx ;(w + h)^2
27+
add edi, esi ;l^2 + (w + h)^2
28+
test edi, 1 ;is result even (last bit 0)?
29+
jz even ;if yes, jump directly to even
30+
31+
mod_8:
32+
mov esi, edi ;any odd perfect square must be 1 (mod 8)
33+
and esi, 7
34+
cmp esi, 1
35+
jne skip_count
36+
jmp even
37+
38+
even:
39+
mov esi, edi ;while n is a power of 4, shift right 2 bits
40+
and esi, 3
41+
test esi, esi
42+
jnz and_7
43+
shr edi, 2
44+
jmp even
45+
46+
and_7: ;if result & 7 != 1, n is not a perfect square
47+
mov esi, edi
48+
and esi, 7
49+
cmp esi, 1
50+
jne skip_count
51+
52+
mov esi, 1 ;prepare for squaretest
53+
mov r8d, 1
4154

42-
exit: ;exit routine, dito
55+
squaretest:
56+
add r8d, 2
57+
add esi, r8d
58+
cmp esi, edi
59+
jl squaretest
60+
jg skip_count
61+
62+
is_square:
63+
cmp ebx, eax ;is w + h <= l?
64+
jle not_greater ;if yes, jump to not_greater
65+
mov edi, ebx ;else calclulate (l - ((w + h + 1) / 2)) + 1
66+
mov esi, eax
67+
inc edi
68+
shr edi, 1
69+
sub esi, edi
70+
inc esi
71+
add ecx, esi ;add result to count and continue
72+
jmp skip_count
73+
74+
not_greater:
75+
mov edi, ebx ;calculate (w + h) / 2
76+
shr edi, 1
77+
add ecx, edi ;and add to count
78+
79+
skip_count:
80+
inc ebx ;next width + height
81+
cmp ebx, edx ;<= 2 * l?
82+
jle next_wh ;if yes, repeat
83+
jmp next_l ;else take next l
84+
85+
finished:
86+
mov ebx, 10
87+
mov ecx, 9
88+
89+
convert_result:
90+
xor edx, edx
91+
div ebx
92+
add edx, '0'
93+
mov [result + ecx], dl
94+
dec ecx
95+
test eax, eax
96+
jnz convert_result
97+
98+
print:
99+
mov eax, 4
100+
mov edi, 1
101+
mov esi, result
102+
mov edx, 12
103+
syscall
104+
105+
exit:
43106
mov eax, 1
44107
xor edi, edi
45108
syscall
46-
47-
section .note.GNU-stack ;just for gcc

0 commit comments

Comments
 (0)