0

I have this short piece of code, its purpose is to sum negative values and count positive ones, the vector is initialized else where

;sum all negative values and count positive values 
    ;let eax hold sum and ebx hold number of positives 
    CALL crlf
    mov ecx, VectorSize
    mov eax, 0
    mov ebx, 0
    mov edx, 0
    sumMe: 
        cmp Vector[edx * TYPE Vector], 0
        jge pos
        ;neg
        add eax, Vector[edx * TYPE Vector]
        INC edx
        loop sumMe 
        pos:
            INC ebx 
            INC edx
            loop sumMe

The piece of code works correctly except when a negative value is the last value in the array, even something like -1 -1 -1 -1 5 works. However if I have a negative value in the last location the program crashes.

Any help would be appreciated

Mitch
  • 3,342
  • 2
  • 21
  • 31
  • With the code you've shown, there's nothing after the loop so your program will always crash when it decodes/executes whatever garbage bytes are next when it eventually leaves the loop. This isn't a [mcve]. – Peter Cordes Feb 09 '18 at 03:26
  • @PeterCordes I print the contents of eax and ebx then exit – Mitch Feb 09 '18 at 03:28

1 Answers1

3

Assuming there's a ret or something at the end:

What does loop do when ecx reaches zero: execution falls through. If the last element was negative, the loop instruction that makes ecx zero is followed by pos:.

When loop runs with ecx=0 to start with, ecx wraps to 0xFFFFFFFF and the jump is taken. loop is like the bottom of a do{}while(--ecx);.

All of this would be obvious if you used a debugger to single-step that last iteration, because you already know the problem is at the end of the array with a negative element.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • Changing out the first `loop` to an unconditional jump to the second `loop` did the trick, thanks – Mitch Feb 09 '18 at 03:39
  • @Mitchel0022: That would make it a bit more like an if/else, but the loop tail-duplication you had before was more efficient. (Although [`loop` itself is slow](https://stackoverflow.com/questions/35742570/why-is-the-loop-instruction-slow-couldnt-intel-have-implemented-it-efficiently) and should generally be avoided). The simple fix is to put a `jmp` *after* the first `loop`, so that exit-from-loop path goes where you want, without adding any instructions inside the loop. Of course, there are plenty of other efficiency improvements I could suggest, like branchless or one load... – Peter Cordes Feb 09 '18 at 03:47