将数组传递给过程,使用 Base+Offset 访问元素

Passing array to a procedure, accessing elements using Base+Offset

我试图在一个过程中循环访问一个 10 元素的 SDWORD 数组。我相信该数组具有所有预期值,因为当我在 main 中显示它们时,它应该是这样的。 当我将数组的地址传递给过程时,第一个元素起作用,但每个后续元素都是 0。我已经尝试了我能想到的所有变体,并且调试器显示了正确的值。我只是不明白问题出在哪里。

当我在 main 中遍历数组时,使用下面的代码,它显示正确。

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

如果我这样做,我得到全 0:

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

我用我手动输入数据的数组测试了相同的代码,它有效。

如果重要的话,调用填充过程的代码是这样的。我使用上面的第一个代码对其进行了测试,它似乎具有所有值。

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

我在这里失去了它,所以任何帮助都会很棒。谢谢。

循环计数器从 ecx 的 10 开始。按照 loop 的工作方式,它递减到零,然后停止。

在每次迭代中:

  • 您正在捕获 ecx 循环计数器(正在倒计时)。
  • 然后从中减去 10

所以对于第一次迭代,你有 10-10,这没问题,但在第二次迭代中你有 9-10(即 -1),第三次迭代,8-10!

你应该单步执行这个并且能够在单步执行期间至少通过两种方式实现这一点:(1)在第二次迭代中减去 10 之后 ebx 为负,以及(2)mov 存储到数组中填充不在数组中的内存 — 数组之前的内存。

我认为您要么没有单步执行,要么没有进行您应该在每条指令后进行的验证。无论哪种方式,您都需要提高调试技能。

与此同时,这段代码的其他部分正在遍历数组,所以这可能就是它找不到相同值的原因。


作为另一种调试技巧,如果您有一行复杂的代码,则用多行更简单的代码代替,例如:

而不是:

mov numArray[ebx * TYPE finalNumber], eax

做这样的事情,这样你就可以观察到所有的中间值。

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

对于最后一个 mov,您应该验证 eax 中的值是否出现在 ebx 引用的内存位置。