почему я не могу переместить 8-битную переменную в гораздо больший 16-битный регистр?
Поскольку для инструкции машинного кода MOV
требуется, чтобы операнд-источник и операнд-приемник были одинакового размера. Это необходимо, потому что инструкция MOV
сама по себе не указывает, как заполнить оставшиеся биты большего регистра назначения.
Чтобы разрешить операции перемещения разного размера, Intel добавила MOVZX
и MOVSX
в ЦП 80386, что позволяет использовать исходный операнд меньшего размера (целевым всегда является 32-битный регистр). Суффиксы -SX и -ZX обозначают, чем должны быть заполнены ранее неиспользованные биты регистра назначения.
На 16-битных процессорах Intel есть инструкция CBW
(Convert Byte to Word), которая расширяет знак от 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
Или, как утверждает Питер Кордес:
xor bx,bx ;clear the whole destination register
mov bl,var1 ;update the least significant byte of the register with the 8-bit value
person
mcleod_ideafix
schedule
27.11.2015
movzx
илиmovsx
, если они доступны, для перемещения с нулевым или знаковым расширением соответственно. Он может быть недоступен в 8086, и в этом случае вам нужно перейти вBL
, как вы сделали, и обнулитьBH
самостоятельно. А почему: потому что они создали такую архитектуру :) - person Jester   schedule 27.11.2015bt*
bit-manip. - person Peter Cordes   schedule 27.11.2015