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
|
; Find the difference between (1+2+3+...+100)^2 and (1^2+2^2+3^2+...+100^2)
; I used another math trick here:
; The sum up to a number can be found using Gauss' Trick:
; 1 + 2 + 3 + ... + 10 -> (1+9) + (2+8) + (3+7) + (4+6) + 10 + 5 -> 5*10 +5
; In general : (n/2)(n+1)
extern printf
SECTION .data
flag: db "%d",10,0 ; "%d\n\0"
SECTION .text
global main
global is_divisible
main:
push rbp ; set up stack
mov rbp, rsp
; first square of sum (1+2+...100)^2
mov rax, 50 ; sum = n/2
mov rcx, 101 ; * (n + 1)
mul rcx
mul rax ; square it
push rax ; save it
; now sum the squares (1^2+2^2 ...) no short cut this time
xor r11, r11 ; This will store the sum, rcx will b n,
; rax is just used to multiply
mov rcx, 0 ; n = 0, we add one first
.loop inc rcx ; see? told you :)
mov rax, rcx ; move into multiply register
mul rax ; multiply by itself
add r11, rax ; add to the sum
cmp rcx, 100
jne .loop
pop rax ; sum of the squares is on the stack
sub rax, r11 ; take the difference, rax - r11
; square of the sum is bigger
.print mov rdi, flag ; arg 1 (format)
mov rsi, rax ; arg 2 (value)
mov rax, 0 ; no xmm registers
call printf wrt ..plt
pop rbp
mov rax, 0
ret
|