在间接寻址中非法使用寄存器
Posted
技术标签:
【中文标题】在间接寻址中非法使用寄存器【英文标题】:Illegal use of register in indirect addressing 【发布时间】:2013-03-12 04:57:12 【问题描述】:我正在尝试编写一个在 x86 汇编 (MASM) 中添加两个大数的子例程。数字由 si 和 di 寄存器指向,函数应该从右到左迭代,添加每个数据字并传递进位,并将结果保存在 di 中。要添加的数据字数由前一段代码决定。
...
mov cx, ( number of data words to add )
adding:
mov bx,cx ;copy the loop counter to bx
lea ax,[di+2*bx] ;move ax to the destination word
adc ax,[si+2*bx] ;add the source word into the destination word
loop adding ;main sub loop
...
不幸的是,当我尝试编译此代码时,我收到错误 A2032:lea 和 adc 行上的寄存器使用无效。我使用的语法有什么问题?
【问题讨论】:
重复问题。总结:寄存器*2是80386+的一个特性,它使用32位寄存器。也使用 mov 代替 lea。 修改标题:原标题与问题关系不大。这也是这个问题的十几个重复的问题——这是一个双周循环的主题。 【参考方案1】:original 8086 addressing modes 仅限于此图表中的组合:
(disp) (base) (offset)
mov [1234] + [bx] + [si], ax
[bp] + [di]
必须从每组中最多选择一项(位移、基数和偏移量)。没有其他组合是有效的。
The 80386 addressing modes 向更正交的方向扩展:
mov al, byte ptr [12345] + [esp + 8 * eax];
这里的变址寄存器都是32位的,esp可以用来直接指向栈变量,缩放项的合法值是1,2,4和8。有了这么多组合指令LEA
可以用于在不更改标志的情况下执行单条指令正交 3 参数加法:[reg1] = [reg2] + [reg3];并执行一些其他算术运算,例如将寄存器乘以 3.5 或 9 的因数。
如果没有 32 位寻址模式,则必须模拟缩放,例如与
mov bx, (N-1)*2 // constant expression
a: mov ax, [bx + di]
adc ax, [bx + si]
sub bx, 2
jns a
另见purpose of LEA instruction。
【讨论】:
值得注意的是,即使在兼容 386 的 CPU 上,16 位寻址模式仍然具有相同的限制,因为二进制机器码编码是相同的。 (没有 SIB 字节,因此所有寻址模式都必须编码到 ModR/M 字节中)。另请参阅我写的这个更大的answer detailing all the x86 addressing modes。以上是关于在间接寻址中非法使用寄存器的主要内容,如果未能解决你的问题,请参考以下文章