Посмотрите на ваши размеры операндов.xpos
только 1 байт, но вы читаете 2 байта с add ax, [xpos]
.Кроме того, mul bl
делает ax = al * bl
, так что вы отбрасываете верхнюю половину результата с кратностью 80.
т.е. set_cursor_pos
возвращается с
di = (( (80*ypos) & 0xff) + (xpos + (ypos<<8)) ) & 0xFF) * 2
Изна ваши предыдущие вопросы вы нацелены на 386-совместимое, поэтому вы можете написать его с помощью
movzx di, byte [ypos]
imul di, di, 80
movzx ax, byte [xpos]
add di, ax
add di, di ; di *= 2. equivalent to shl di, 1 but more efficient.
(80 = 16 * 5, чтобы вы также могли избежать imul
и использовать один lea di, [edi + edi*4]
/shl di, 4
. Или любой трюк, совместимый с 8086, для умножения на число с таким количеством установленных битов.)
Нет смысла использовать mul
для умножения на 2, если только вы не собираетесь использовать mul bx
и использовать полный 32-битный результат в dx:ax
.Но даже тогда, для 2 вы должны просто использовать add di,di
/ setc al
, потому что вынос может быть только 1 бит.
Если xpos
и ypos
были 16-битными, вы могли бы использоватьони как операнды памяти:
imul di, [ypos], 80
add di, [xpos]
add di, di ; di *= 2
Или, конечно, вы могли бы сначала хранить их в регистрах.