将数组传递给过程,使用 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
引用的内存位置。
我试图在一个过程中循环访问一个 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
引用的内存位置。