Now i'm not asking for a complete easy answer or source, so please take the time to help me. I would like a very detailed explanation telling what to do, I have no idea. I am very confused by stacks, functions, pushing, popping, and all that. I am very new to assembly and my class just completed arrays and went on to functions. In addition, I am just now learning C on the side with assembly while taking another advanced java course. Therefore, I am pretty new to C and its concepts. Although I have read "The C Language" several times and own it.

Here is my assignment:

Write an assembly language function sumPowers such that sumPowers(n) will be the sum 1+2+2^2+2^3+...2^n  For example, the value of sumPowers(5) should be 64 (the sum of 1,2,4,8,16,32).  Your function is to do no input or output--communicating with the user is to be done by the program that calls your function.  Your function is to be callable as though it had the following prototype:

int sumPowers(int n);

You are, of course, to write a suitable main program that calls sumPowers and to use this main program to test your function.  Your main program is to use scanf and printf to do suitable input and output.

Note:  In all the parts of this assignment you are to follow the usual Pentium conventions for passing parameters, returning values, and using registers.

I'm thinking store the number n in an array that has all its elements decremented by 1 from the original number and set. Reverse it so its in ascending order, or use a loop to initialize an array [1,2,3,4,5...n]. Then use a second array containing the elements: [1,2,2,2,2.....n(replaced with 2] using some kind of compare statement to initialize the elements. So you would compare *p1 (pointer 1 at array 1 which is 1,2,3,4,5....n) to 1. If its not equal to 1, move a 2 into the new empty array 2 which was initialized with n 0s. Then, reset the pointers back to the start of both arrays subtracting N iterations * 4 (because every iteration up an array is 4 bits) to the pointers. Using a third array to store the values; multiply array 2 (1,2,2,2,2...n(replaced by 2)) by itself the number of times array 1 (1,2,3,4,5...n) is pointing to. The logic seems to be all comprehensive, however the stack management involved is not to me.

Please help,
Thank You!

Updated Code:

[SECTION .text]
global  sumPowers
        global  main
sumPowers:
        push    EBP
        mov     EBP, ESP
        push    EBX
        push    EDI
        push    ESI

        mov     EBX, [EBP+12]   ; Store the address of the array in EBX
        mov     EDI, [EBP+8]    ; Store n in EDI
        mov     ECX, 10         ; Store the length of the array in ECX
        mov     EAX, 0          ; Initialize the counter
        mov     ESI, EDI        ; Store n in ESI
        sub     ECX, EDI        ; Store (10-n) in ECX

loop1:  cmp     EAX, ECX        ; Test whether the pointer to the (10-n) value
                                                     ; or not
        je      step1
        add     EBX, 4          ; Point to next value
        add     EAX, 1          ; Increment the counter
        jmp     loop1

step1:  mov     EAX, 0          ; Initialize the sum
        mov     EDX, 10

Step2:  cmp     EDX, ECX        ; Loop n times
        je      next
        add     EAX, [EBX]      ; Store the sum in EAX
        add     EBX, 4          ; Point to the next value
        add     ECX, 1          ; Increment the counter
        jmp     step2

next:   pop     ESI
        pop     EDI
        pop     EBX
        mov     ESP, EBP
        pop     EBP
        ret

My function is written now I just need to write the driver. "You are, of course, to write a suitable main program that calls sumPowers and to use this main program to test your function. Your main program is to use scanf and printf to do suitable input and output."

Update: My program now works. However, Whenever I attempt to debug it using gdb I recieve a strange error. When the function is returning to the main program I get the error:

start () at ../sysdeps/i386/elf/start.S:105
105     ../sysdeps/i386/elf/start.S: No such file or directory.
        in ../sysdeps/i386/elf/start.S

Somehow, I caused the assembler to bug.....

Here is a copy of the final source:

[SECTION .data]

n:      dd      0
fmt1:   db      "%d", 0
fmt2:   db      "%d", 10, 0

[SECTION .text]

        global  main
        extern scanf, printf

main:   push    EBP
        mov     ESP, EBP
        push    EBX
        push    ESI
        push    EDI

first:
        push    n
        push    fmt1
        call    scanf
        add     ESP, 8

cool:
        mov     EDI,[n]
        push    EDI
        call    sumPowers
        add     ESP, 4

        push    EAX
        push    fmt2
        call    printf
        add     ESP, 8

last:   pop     EDI
        pop     ESI
        pop     EBX
        mov     ESP, EBP
        pop     EBP
        ret

sumPowers:
        push    EBP
        mov     ESP,EBP

        mov     ECX, 2
        mov     EBX, 2
        mov     EDX,3
        mov     EAX, 0          ; Initialize the counter
        mov     ESI, EDI        ; Store n in ESI
        sub     ESI,1

loop1:  cmp     EAX, ESI        ; 
        jge     step1
        imul    ECX,EBX
        add     EDX,ECX
        add     EAX,1
        jmp     loop1
 
step1:  mov     EAX, ECX        ; Initialize the sum
        pop EBP
        ret

Found the error! I did mov ESP, EBP in both main and last. That is the reverse effect of what I wanted. Thanks to myself for solving my own problem!

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.