在间接寻址中非法使用寄存器

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。

以上是关于在间接寻址中非法使用寄存器的主要内容,如果未能解决你的问题,请参考以下文章

汇编语言ARM扩展资料数据寻址

8086中的七种寻址方式

(计算机组成原理)第四章指令系统-第二节2:数据寻址(直接寻址间接寻址立即数)

什么是ip寻址

计算机组成原理——指令系统

ARM 指令之寄存器间接寻址的几种表达方式