Hello I'm new to assembly and it would be nice if anyone could give me feedback and/or constructive critic on the code I write. All the exercises are from Project Euler. Note: All codes are invoked from a C Function.
Okay so the first is find the multiples of 3 or 5.
http://projecteuler.net/problem=1segment .text
global _multiply_3_or_5
; Parameter: int max
; Description: returns the sum of all multiplies from 3 OR 5
_multiply_3_or_5:
push ebp
mov ebp, esp
mov ebx, 0
mov ecx, [ebp + 8] ;i = max
loop_start: ;for (i = max; i > 0; i--)
push 3
push ecx
call modulus
test eax, eax ;i % 3 == 0
jne skip_3
add ebx, ecx
jmp skip_5 ;i % 3 == 0 || i % 5 == 0
; ^^
skip_3:
push 5
push ecx
call modulus
test eax, eax ;i % 5 == 0
jne skip_5
add ebx, ecx
skip_5:
loop loop_start
mov eax, ebx ;return sum;
mov esp, ebp
pop ebp
ret
;multiply_3_or_5
; Parameters: int a, int b
; Returns: a % b
modulus:
push ebp
mov ebp, esp
push ecx
xor edx, edx
mov eax, [ebp + 8] ;a
mov ecx, [ebp + 12] ;b
div ecx ;edx holds remainder (a % b)
mov eax, edx ;return remainder
pop ecx
mov esp, ebp
pop ebp
ret 8
;modulus
The next one is to sum the even values of a fibonacci sequence that didn't exceed 4 million.
http://projecteuler.net/problem=2segment .text
global _fibonacci
_fibonacci:
push ebp
mov ebp, esp
sub esp, 16
mov dword [ebp - 4], 0 ;x = 0
mov dword [ebp - 8], 1 ;y = 1
mov dword [ebp - 16], 0 ;sum
do:
mov eax, [ebp - 4] ;eax = x
mov ebx, [ebp - 8] ;edx = y
add eax, ebx ;eax += y
mov [ebp - 4], ebx ;x = y
mov [ebp - 8], eax ;y = z
push 2
push dword [ebp - 8]
call modulus ;eax = 2 % y
test eax, eax
jne skip_add
mov eax, [ebp - 16]
add eax, [ebp - 8]
mov [ebp - 16], eax ;sum += y
skip_add:
cmp dword [ebp - 8], 4000000
jle do
mov eax, [ebp - 16]
mov esp, ebp
pop ebp
ret
; Parameters: int a, int b
; Returns: a % b
modulus:
push ebp
mov ebp, esp
push ecx
push edx
xor edx, edx
mov eax, [ebp + 8] ;a
mov ecx, [ebp + 12] ;b
div ecx ;edx holds remainder (a % b)
mov eax, edx ;return remainder
pop edx
pop ecx
mov esp, ebp
pop ebp
ret 8
;modulus
-skipped couple problems because they are to hard for me-
The following exercise I made is the smallest evenly divisible by all numbers 1 - 20
http://projecteuler.net/problem=5section .text
global _smallest_multiply
_smallest_multiply:
push ebp
mov ebp, esp
mov ebx, 0 ; smallest_multply (num)
loop_start:
mov ecx, 20 ; i = 20
inc ebx ; num++
for_loop: ; for (; ecx > 0; ecx--)
push ecx
push ebx
call modulus ; eax = edx % ecx (num % i)
test eax, eax
jne loop_start ; if (eax != 0) goto loop_start;
loop for_loop
mov eax, ebx ; set return value
mov esp, ebp
pop ebp
ret
; Parameters: int a, int b
; Returns: a % b
modulus:
push ebp
mov ebp, esp
push ecx
xor edx, edx
mov eax, [ebp + 8] ;a
mov ecx, [ebp + 12] ;b
div ecx ;edx holds remainder (a % b)
mov eax, edx ;return remainder
pop ecx
mov esp, ebp
pop ebp
ret 8 ;learned this is important xd
;modulus
Then a easy one was to find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.
http://projecteuler.net/problem=6section .text
global _sum_square_difference
_sum_square_difference:
push ebp
mov ebp, esp
sub esp, 0x0C
mov dword [ebp - 4], 0 ;sum of 1 - 10 (x)
mov dword [ebp - 8], 0 ;sum of 1^2 - 10^2 (y)
mov ecx, 100 ;i = 100
loop_start: ;for (int i = 100; i > 0; i--)
add [ebp - 4], ecx ;x += i
mov eax, ecx
mul eax
add [ebp - 8], eax ;y += i * i
loop loop_start
mov eax, [ebp - 4]
mul eax ;x * x
sub eax, [ebp - 8] ;x - y
mov esp, ebp
pop ebp
ret
Then I had to find the 10001st prime number:
http://projecteuler.net/problem=7 ; Parameters: int x
; Description: find the x'st prime number
_x_prime:
push ebp
mov ebp, esp
sub esp, 4
mov [ebp - 4], dword 1 ; first prime number
push ecx
mov ecx, 0
.for_loop:
push dword [ebp - 4]
call _next_prime ; next_prime(local_int)
mov [ebp - 4], eax ; store the next prime number
inc ecx ; i++
cmp ecx, [ebp + 8]
jl .for_loop ; i < x
pop ecx
mov esp, ebp
pop ebp
ret 4
;_x_prime
; Parameters: int prev_prime
; Description: get the next prime number, from prev_prime
_next_prime:
push ebp
mov ebp, esp
push ecx ; save ecx
mov ecx, [ebp + 8] ; ecx = prev_prime
.loop:
inc ecx
push ecx
call _is_prime ; is_prime(ecx)
test eax, eax
jne .break ; ecx is prime number, so break it
jmp .loop ; goto loop
.break:
mov eax, ecx ; store return value
pop ecx ; restore ecx
mov esp, ebp
pop ebp
ret
;_next_prime
; Parameters: int a
; Description: checks if number is a prime
_is_prime:
push ebp
mov ebp, esp
sub esp, 4
push edx ; saves register
mov edx, [ebp + 8] ; hold parameter in edx
mov [ebp - 4], dword 2 ; int i = 2
.for_loop:
push dword [ebp - 4]
push edx
call modulus
test eax, eax
je .test_prime
inc dword [ebp - 4] ; i++
cmp [ebp - 4], edx
jl .for_loop ; i < a
.test_prime:
cmp [ebp - 4], edx
jne .else ; if (i != num) goto else;
mov eax, 1 ; eax = 1 (true)
jmp .end ; goto end; (skip the else block)
.else:
mov eax, 0 ; eax = 0 (false)
.end:
pop edx ; remember to restore it!!
mov esp, ebp
pop ebp
ret 4
;_is_prime
; Parameters: int a, int b
; Description: returns a % b (the remainder)
modulus:
push ebp
mov ebp, esp
push ecx
push edx
xor edx, edx
mov eax, [ebp + 8] ;a
mov ecx, [ebp + 12] ;b
div ecx ;edx holds remainder (a % b)
mov eax, edx ;return remainder
pop edx
pop ecx
mov esp, ebp
pop ebp
ret 8
;modulus
These are the ones I solved at this moment, it would be nice if anyone could review the code give me some feedback, or how you would do it etc. Just everything that I can learn from would be nice to know!
Regards