Я очень новичок и читал ассемблер для x86 от Irvine. Я нахожусь в разделе о целочисленном делении со знаком и наткнулся на пример, который меня действительно смущает.
Это пример того, что происходит, когда вы не подписываете exten. Вот строка кода:
.data
wordval SWORD -101 ;009Bh
.code
mov DX, 0
mov ax, wordVal ; DX:AX = 0000009Bh (+155)
mov bx, 2 ; BX is the divisor
idiv bx ; divide DX:AX by BX (signed operation)
Затем говорится, что, поскольку ax действительно равен +155, полученное отношение составляет +77 вместо ожидаемого результата.
Почему -101
, представленный в переменной wordVal как 009B вместо FF9B во второй строке кода?
Вот моя логика: десятичное число 101 равно 65h. SWORD равен 16 битам, поэтому дополнение к ним должно быть 0FF9Bh. Тогда DX устанавливается в 0 и DX: AX будет равен 0000FF9Bh, поэтому, если нет расширения знака, число будет интерпретироваться как десятичное число 65435.
Я бы ожидал, что код будет читаться следующим образом:
.data
wordval SWORD -101 ;FF9Bh
.code
mov DX, 0
mov ax, wordVal ; DX:AX = 0000FF9Bh (+65435)
mov bx, 2 ; BX is the divisor
idiv bx ; divide DX:AX by BX (signed operation)
с частным 32717.
(Или с нормальным cwd
в качестве настройки для 16-битного idiv
, он фактически вычислит -101 / 2
= -50
остаток -1
. Или с арифметическим сдвигом вправо для эффективного деления на 2, AX = -51
с CF = 1.)
Это ошибка в книге или я что-то упустил?