Home > front end >  Passing array to a procedure, accessing elements using Base Offset
Passing array to a procedure, accessing elements using Base Offset

Time:04-09

I am trying to iterate through a 10 element SDWORD array in a procedure. I believe the array has all the expected values, because when I display them in main, it is how it should be. When I pass the address of the array to a procedure, the first element works, but every subsequent element is 0. I've tried every variation I can think of, and the debugger shows the correct values. I just can't understand where the problem is.

When I iterate through the array in main, using the below, it displays correctly.

    mov  ecx, 10    
        _displayTemp:       
             mov    ebx, ecx        
             sub    ebx, 10         
             mov    eax, numArray[ebx * TYPE finalNumber]       
             call   WriteInt        
             call   CrLf    
         loop   _displayTemp

If I do this, I get all 0s:

push OFFSET numArray    
call    bobBilby  

bobBilby PROC 

    push    ebp 
    mov ebp, esp
    mov esi, [ebp   8]
    mov eax, [esi   4]
    call    WriteInt
    call    CrLf
    mov eax, [esi   8]
    call    WriteInt
    call    CrLf
    mov eax, [esi   12]
    call    WriteInt
    call    CrLf
    ret 4

bobBilby ENDP

I've tested the same code with an array I manually input the data into, and it works.

If it matters, the code to call the filling procedure is this. I used the first code above to test it, and it appears to have all the values.

mov ecx, 10     
_fillArray:         
     mov    ebx, ecx        
     sub    ebx, 10                 
     <lots of push OFFSETs>         
     call   ReadVal         
     mov    eax, finalNumber        
     mov    numArray[ebx * TYPE finalNumber], eax   
loop    _fillArray

I am losing it here, so any help would be awesome. Thank you.

CodePudding user response:

The loop counter starts in ecx at 10.  And the way loop works, it decrements to zero, then stops.

In each iteration:

  • you're capturing the ecx loop counter (which is counting down).
  • then subtract 10 from that

So for first iteration, you have 10-10, which is ok, but on the second iteration you have 9-10 (which is -1), third iteration, 8-10!

You should be single stepping this and be able to realize this at least two ways during single stepping: (1) that ebx is negative after this subtract of 10 on the second iteration, and (2) that the mov to store into the array populates memory that isn't in the array — memory that is before the array.

I would submit that you're either not single stepping, or not doing the verification you should be doing after each instruction.  Either way, you need to develop your debugging skill.

Meanwhile, other parts of this code are going forwards through the array, so that's probably why it is not finding the same values.


As another debugging technique, if you have a complex line of code, then substitute with multiple simpler lines of code, for example:

instead of:

mov numArray[ebx * TYPE finalNumber], eax

do something like this so you can observe all the intermediate values.

sll ebx, 2                # verify ebx is right
add ebx, offset numArray  # verify the pointer value in ebx
mov [ebx], eax            # should be able to see exactly where stored

With that last mov, you should verify that the value in eax appears at memory location referred to by ebx.

  • Related