我无法理解如何遍历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数组的平面内存.