Не работает функция idiv? -7/7 = 35 и ещё какая то ерудна в регистре дх

 "mov al, %1    ;" //положили x в AL
 "cbw           ;" //расширяем AL до AH, чтобы потом произвести умножение
 "sub ax, 3     ;" //отняли от x 3 и поместили в регистр АX
 "imul %2       ;" //умножаем AX на переменную y и записываем в регистры DX AX
 "sub ax, 2     ;" //вычитаем из младшего слова 2
 "sbb dx, 0     ;" //вычтем по правилу для длинных слов (от старшего слова отнимем ноль и учтем флаг переноса)
 "mov cx, ax    ;" //прячем значение младшего слова в CX
 "mov al, %3    ;" //помес`введите сюда код`тить z в AL
 "cbw           ;" //расширяем AL до AH
 "add ax, 3     ;" //прибавляем 3
 "mov bx, ax;" //меняем местами для того, чтобы выполнить деление
 "mov ax, cx;   "
 "idiv bx       ;" //делим пару dx:ax на сх и получаем результат в ax
 "mov %0, ax    ;" //результат - в vas
 ".att_syntax   ;"
 :"=r"(vas)
 :"r"(x), "r"(y), "r" (z)
 : "ax", "bx", "cx", "dx"
x = -0x2; y = 0x1; z = 0x4;

Совершенно не понимаю в чем может быть проблема, помогите поджалуйста


Ответы (1 шт):

Автор решения: user22405329

В вашей ассемблерной вставке нет перевода строк, компилятор передаёт ассемблеру одну большую строку. Поскольку первая строка заканчивается точкой с запятой — ассемблер считает весь ваш код комментарием и игнорирует. Нужно каждую строку оканчивать на \n:

"mov al, %1    \n" //положили x в AL
"cbw           \n" //расширяем AL до AH, чтобы потом произвести умножение

Также обратите внимание, что переменная y должна иметь тип short — иначе imul %2 будет 8-биной инструкцией AX=AL*y, которая не записывает ничего в DX.

Ну и конечно же переменные нужно инициализировать до ассемблерной вставки, а не после, а в начале вставки добавить .intel_syntax noprefix\n.

→ Ссылка