无法将8位地址移动到16位寄存器

时间:2015-11-27 14:25:11

标签: assembly x86 x86-16 emu8086

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

       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. 我是汇编语言的新手,所以如果这是一个愚蠢的问题我会道歉。

2 个答案:

答案 0 :(得分:5)

  

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

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

为了允许不同大小的移动操作,英特尔在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

答案 1 :(得分:0)

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

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

NASM会按照你的说法做,并做16位负载。您会在var1中找到bl,在var2找到bh。大概你可以编写mov bx, word [var1]word ptr或其他什么来让你的汇编程序发出16位负载。

(实际上,NASM会将mov BX, var1汇集到mov r16, imm16中,将地址放入寄存器。为了保持一致性,请始终在内存引用周围使用[]。因为它适用于NASM和MASM英特尔语法的变体。但NASM不支持编写mov-immediate表单的mov BX, offset var1语法。)