数组 – 遍历2维数组

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

问题是// 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

最佳答案 请参阅
x86标记维基,包括
list of addressing modes.

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

re:edit:* dim应该可以工作,如果dim定义为dim equ 8.如果它是一个保存值的内存位置,那么它当然不会起作用.比例因子可以是1,2,4或8.(机器代码格式有2位移位计数的空间,这就是选项有限的原因.)

我还建议加载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

imul   edx, esi
test   0x80, byte ptr [edi + edx]   ; AND, discard the result and set flags.
jnz

当然,您可以在外循环中添加列,而不是在内循环内部进行乘法运算.这称为Strength Reduction.所以你沿着每一行做p = 1,p = cols从一行到另一行.或者,如果您不需要关心行和列,则可以迭代2D数组的平面内存.

点赞