HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

Sum up all odd numbers between 1 and 2n + 1

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
allnumbersbetweensumandodd

Problem

Assignment:


Write a program which reads a number n from the console. Then
calculates the sum of all odd numbers between 1 and 2n + 1 (incl.).

Assignment also on GitHub, Exercise 0.0.

The functions read_hex and print_eax as well as the header and tail of the script are provided by the tutor.

format PE console
entry start

include 'win32a.inc' 

; ===============================================
section '.text' code readable executable

start:
    call    read_hex

    mov     esi, 1 ; esi becomes the counting variable.

    mov     ebx, 2
    mul     ebx
    add     eax, 2
    mov     edi, eax ; edi becomes the limit.

    mov     eax, esi    
    mov     ebx, 2 ; Will be the divisor.   
    mov     ecx, 0 ; ecx will store the sum.
operationSet:
    mov edx, 0 ; Make sure that the register is empty.
    div ebx

    cmp edx, 0
    JE manageOperationSet ; If 0 then skip next operation.
    add ecx, esi   
manageOperationSet:
    inc esi
    mov eax, esi
    cmp esi, edi
    jne operationSet

    mov eax, ecx
    call print_eax

    push    0
    call    [ExitProcess]    
include 'training.inc'


I've tested my program with the numbers from 1 to 6 and get correct results. I think it works correctly, but I'm not sure concerning my register usage.

Moreover: What could be improved? Are there weak points in my code?

Solution

Random thoughts:

  • A comment that indicates what/where read_hex returns might be useful.



  • mov ebx, 2; mul ebx could probably be replaced with shl eax,1.



  • While div can be used to check for 'oddness', I believe it is an expensive solution. How about bt?



  • In fact, why check for oddness every iteration of the loop? Check once at the top and count by 2's.



  • If you aren't using mul/div, then you don't have to have values in specific registers. This might help you avoid moving values from one register to another so much.



But my biggest piece of advice is to junk this whole approach and start over.

I've tried to calculate some solutions here (let me know if I've got this wrong):

n   result
0   1
1   4
2   9
3   16
4   25


Do you notice anything interesting about the numbers in the right-hand column? Here's a hint, but before you hover over it, take a moment to try to puzzle it out yourself. You'll feel better if you do.


11 = 1, 2 2 = 4, 3 3 = 9, 44 = 16, 5 * 5 = 25

Or in other words:


(n+1)2

With that in mind, there's a much faster/simpler way to calculate results, especially if n is big.

Code Snippets

n   result
0   1
1   4
2   9
3   16
4   25

Context

StackExchange Code Review Q#141000, answer score: 7

Revisions (0)

No revisions yet.