5

我正在尝试分配变量来注册这里是代码:

       ORG 100h

        var1 DB 10  ;
        var2 DB 20  ;

        MOV BX,var1 ; error : operands do not match: 16 bit register and 8 bit address
RET
END

但如果将第 4 行换成:

MOV BL, var1;

有用。所以我的问题是为什么我不能8 位变量移动到更大的 16 位寄存器中?

我已经提到了 thisthisthis OP,但它没有回答我的问题。

笔记:

  1. 我正在使用 emu8086 汇编程序
  2. 我是汇编语言的新手,所以如果这是一个愚蠢的问题,我深表歉意。
4

2 回答 2

7

为什么我不能将 8 位变量移动到更大的 16 位寄存器中?

因为机器代码MOV指令需要源操作数和目标操作数的大小相同。这是必需的,因为MOV指令本身并未指定如何填充较大目标寄存器的剩余位。

为了允许不同大小的移动操作,Intel 在 80386 CPU 中添加了MOVZXMOVSX,它允许更小的源操作数(目标始终是 32 位寄存器)。-SX 和 -ZX 后缀表示目标寄存器中以前未使用的位应该填充什么。

在 16 位 Intel 处理器上,有指令CBW(将字节转换为字),该指令将符号从 8 位扩展到 16 位。不幸的是,这仅适用于累加器(寄存器 AL/AX),因此您必须执行以下操作:

mov al,var1
cbw
mov bx,ax

cbw做一个符号扩展。如果你var1没有签名,你可以这样做:

mov bl,var1
xor bh,bh  ; equivalent to mov bh,0 but faster and only one byte opcode

或者,正如 Peter Cordes 所说:

xor bx,bx    ;clear the whole destination register
mov bl,var1  ;update the least significant byte of the register with the 8-bit value
于 2015-11-27T14:50:41.977 回答
1

您正在使用一个汇编程序来跟踪您如何声明符号以确定要使用的操作数大小。

var1不是一个 8 位地址,它是一个 16 位地址(不计算段),它指向两个 8 位变量中的第一个。因此,汇编程序错误消息措辞不当且令人困惑。

NASM 会按照你说的做,并进行 16 位加载。你会发现var1inblvar2in bh。大概你可以写mov bx, word [var1]word ptr或者其他什么,让你的汇编器发出 16 位负载。

(实际上,NASM 会组装mov BX, var1 成 a mov r16, imm16,将地址放入寄存器。始终使用[]内存引用以保持一致性,因为这适用于 Intel 语法的 NASM 和 MASM 变体。NASM 不支持mov BX, offset var1编写 mov-immediate 的语法不过形式。)

于 2015-11-27T14:50:24.947 回答