遍历二维数组

use*_*136 5 arrays x86 assembly

我无法理解如何用 x86 汇编语言遍历二维数组。我缺少一点理解。这是我到目前为止所拥有的。

问题是带有//offsetand的行//moving through array 对于//offset我得到的错误是“第二个操作数中的非常量表达式”以及“ebx:第二个操作数中的非法寄存器”

对于下一行,我收到错误“edx:第二个操作数中的非法寄存器”

    mov esi, dim
    mul esi
    mov eax, 0 // row index
    mov ebx, 0 // column index
    mov ecx, dim
StartFor:
    cmp ecx, esi
    jge EndFor
    lea edi, image;
    mov edx, [eax *dim + ebx] // offset
    mov dl, byte ptr [edi + esi*edx] // moving through array
    mov edx, edi
    and edx, 0x80
    cmp edx, 0x00
    jne OverThreshold
    mov edx, 0xFF


OverThreshold:
    mov edx, 0x0
Run Code Online (Sandbox Code Playgroud)

Pet*_*des 1

请参阅标签 wiki,包括寻址模式列表

您可以按常数缩放索引寄存器,但不能在寻址模式下将两个寄存器相乘。您必须自己执行此操作(例如imul edx, esi,如果列数不是编译时间常数,则使用 。如果它是 2 的幂常数,则可以进行移位,甚至使用缩放寻址模式,例如[reg + reg*8])。


回复:编辑: 如果用类似 的东西定义,*dim应该可以工作。如果它是一个保存值的内存位置,那么它当然不起作用。比例因子可以是 1、2、4 或 8。(机器代码格式具有用于 2 位移位计数的空间,这就是选项受到限制的原因。)dimdim equ 8


我还建议加载 来将movzx字节零扩展为edx,而不是仅写入dl(低字节)。实际上 nvm,你的代码不需要它。事实上,您覆盖了加载的值edi。我认为这是一个错误。


您可以更换

imul  edx, esi
mov dl, byte ptr [edi + edx]   ; note the different addressing mode
mov edx, edi                   ; bug?  throw away the value you just loaded
and edx, 0x80                  ; AND already sets flags according to the result
cmp edx, 0x00                  ; so this is redundant
jne OverThreshold
Run Code Online (Sandbox Code Playgroud)

imul   edx, esi
test   0x80, byte ptr [edi + edx]   ; AND, discard the result and set flags.
jnz
Run Code Online (Sandbox Code Playgroud)

当然,您可以只在外循环中添加,而不是columns在内循环中相乘。这就是所谓的强度缩减。所以你要p+=1沿着每一行进行,并p+=cols逐行进行。或者,如果您不需要关心行和列,则可以只迭代二维数组的平面内存。