0

Hey guys so I am having trouble with this problem for class. So the problem is to add the sum of an array with in a range. The issue I am having is that I can't get the second conditional statement to work, jumping to L4. I am sure there are other issues with the coding so I am completely open to know those issues as well. Thanks in advance guys.

; Program template


Include Irvine32.inc

.data
list DWORD 10, 20, 30, 40
ptrA SDWORD list
varj DWORD 25
vark DWORD 100

.code
main proc
mov esi, ptrA
mov ecx, LENGTHOF list
call ArraySum
call WriteDec

invoke ExitProcess,0
main endp

ArraySum Proc
push esi
push ecx
mov eax, 0
mov ebx, varj
mov edx, vark

top:
cmp [esi], ebx   ; if esi > ebx
jg L2             ; jump to L2
jl L4             ; else jump to L4


L2:
cmp [esi], edx    ;if esi < edx
jl L3            ; jump to L3
jg L4            ; else jump to L4

L3:
add eax, [esi]            ;add the value in array into eax
add esi, TYPE DWORD        ; move to next array index
loop top                ; loop to top

 L4:
 add esi, TYPE DWORD        ; move ot next array index
 loop top                ; loop to top

pop ecx
pop esi
ret
ArraySum endp

end main
rkhb
  • 14,159
  • 7
  • 32
  • 60
Bryan
  • 117
  • 3
  • 13
  • Sorry. I am using Microsoft (MASM), so I believe it's opposite for the cmp. Also, sorry let me update the code. Thanks – Bryan Jun 11 '15 at 18:33
  • From what I have gathered cmp A,B is translated to A - B, Ex :http://stackoverflow.com/questions/9617877/assembly-jg-jnle-jl-jnge-after-cmp – Bryan Jun 11 '15 at 18:44
  • Yep, sorry about that. You're right about the `cmp`. Could still use an explanation of what's not working, though. – lurker Jun 11 '15 at 18:54
  • Sorry about the miscommunication. At work currently. So I have to add the array in between the values of varj and vark. So I want to compare the first index of the array to varj and if it doesn't check out then go to L4. If it is greater then go to L3 to make sure it is less then vark. If not, go to L4 and skip the index. So, the issue I am having is that when I implement the varj to try and get it to jump to L4, it doesn't. Hope this helps. – Bryan Jun 11 '15 at 19:08
  • mov ecx, LENGTHOF list – Bryan Jun 11 '15 at 19:25
  • I take it `WriteDec` writes out the value that's in `eax`? – lurker Jun 11 '15 at 19:27
  • I think your problem is between `L3` and `L4`. When the `loop` at the end of `L3` finally completes (`ecx` goes to zero), it will drop down into the `L4` section which loops again, decrementing `ecx` to `0xFFFFFFFF`. You really only need one `loop` section. The `L4` label should go before your first `add esi, TYPE DWORD`. – lurker Jun 11 '15 at 19:31
  • Hm. Doesn't ECX only decrement when the loop completes. So, it won't decrement until it reaches a TOP label? – Bryan Jun 11 '15 at 19:37
  • `loop` decrements `ecx` on every iteration and terminates (no longer takes the jump to the given label) when the result is zero after the decrement. When your first `loop` decrements it to zero, that loop will then not take the jump to `top` but will fall through to the `L4` section, and the next loop will decrement again to `0xFFFFFFFF` and take the jump to `top`. See the [LOOP instruction documentation](http://x86.renejeschke.de/html/file_module_x86_id_161.html). – lurker Jun 11 '15 at 19:39

1 Answers1

1

There is an error in the way you're handling your loop instruction, and you have bits of redundant code.

Your current looping section is as follows:

L3:
    add eax, [esi]            ;add the value in array into eax
    add esi, TYPE DWORD        ; move to next array index
    loop top                ; loop to top

L4:
    add esi, TYPE DWORD        ; move ot next array index
    loop top                ; loop to top

If the first loop instruction decrements ECX to 0, it will complete and not take the jump but fall through to the L4 section. The loop instruction in the L4 section will then decrement ECX to 0xFFFFFFFF and you're going to get a lot more looping back to the top label as the loop instructions proceed to decrement your new, very large ECX value to 0.

The redundancy comes from constructs such as this:

    jg L2             ; jump to L2
    jl L4             ; else jump to L4
L2:

Here, if the result is greater than zero, you land on L2. If it's less than zero, you land on L4. If it's equal to zero, you fall through to L2. The net result is that you are really wanting to go to L4 if the result is less than zero, and fall through to L2 otherwise. So this is equivalent to, simply:

    jl L4
L2:

Here's the same function with the loop issue removed and the redundancy tidied up a bit. (NOTE this still assumes that ecx, the array length, and esi, the array address, have been loaded by the caller.)

ArraySum Proc
    push  esi
    push  ecx
    mov   eax, 0
    mov   ebx, varj
    mov   edx, vark

top:
    cmp   [esi], ebx         ; if [esi] < ebx
    jl    skip               ;     jump to skip

    cmp   [esi], edx         ; if [esi] > edx
    jg    skip               ;     jump to skip

    add   eax, [esi]         ; add the value in array into eax

skip:
    add   esi, TYPE DWORD    ; move to next array index
    loop  top                ; loop to top

    pop ecx
    pop esi
    ret
ArraySum endp
lurker
  • 56,987
  • 9
  • 69
  • 103