Author Topic: Review my code!  (Read 14107 times)

Offline iVision

  • Jr. Member
  • *
  • Posts: 22
Review my code!
« on: July 23, 2013, 07:34:19 PM »
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=1
Code: [Select]
segment .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=2
Code: [Select]
segment .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=5
Code: [Select]
section .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=6
Code: [Select]
section .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
Code: [Select]
; 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

Offline encryptor256

  • Full Member
  • **
  • Posts: 250
  • Country: lv
  • Win64 .
    • On Youtube: encryptor256
Re: Review my code!
« Reply #1 on: July 24, 2013, 02:34:30 PM »
Hi!

All your code is readable, that's good and i like your coding style. :)

I knew nothing about project euler before now.

So, thanks to you,
now i know what is project euler,
now i will join project euler too,
a lot of challenges for me. :)

I cant tell you how "what do to", because im gonna start now. :D

It will be a good experience doing all of them in NASM. :)

Thanks!
Encryptor256's Investigation \ Research Department.

Offline iVision

  • Jr. Member
  • *
  • Posts: 22
Re: Review my code!
« Reply #2 on: July 24, 2013, 03:06:38 PM »
Hi!

All your code is readable, that's good and i like your coding style. :)

I knew nothing about project euler before now.

So, thanks to you,
now i know what is project euler,
now i will join project euler too,
a lot of challenges for me. :)

I cant tell you how "what do to", because im gonna start now. :D

It will be a good experience doing all of them in NASM. :)

Thanks!

Okay cool! Share your solutions here so I can compare mine with yours! Yesterday I created a small tampermonkey script (javascript) for a random button if you are interested:
https://dl.dropboxusercontent.com/u/44845826/ProjectEuler%20Random%20Button.tamper.js