Вычислить значение выражения: ((2*c)-(d/3)) / (b-(a/4)) - Assembler
Формулировка задачи:
Имеется пример ((2*c)-(d/3)) / (b-(a/4))
При клике на Btn1 значение выводится в Edit1
В качестве тестовых чисел я взял: a - 20 b - 10 c - 10 d - 30.Итоговый ответ должен получиться (20-(30/3))/(10-(20/4))=10/5=2
Использую ассемблерную вставку в Delphi
Сама ошибка - [Error] Unit1.pas(58): Operand size mismatch , выводится на mov c,bl , видимо ошибся в регистрах где-то, прошу указать на ошибку и подсказать как мне вывести значение, выводится в Edit1.
Так же готов выслушать советы по оптимизации, возможно где-то сделал лишние операции.
procedure TForm1.BitBtn1Click(Sender: TObject); var c:word; begin asm // умножение 2 на 10 mov al,2 mov cl,10 imul cl mov bl,al //деление 30 на 3 mov ax,30 mov cl,3 div cl mov dl,al // подсчёт числителя sub bl,dl // деление 20 на 4 mov ax,20 mov cl,4 div cl mov dl,al //разница 10 и предыдущего слагаемого mov al,10 sub al,dl // подсчёт знаменателя idiv bl // передача значения переменной mov c,bl end; form1.Edit1.text:=inttostr(c); end;
Решение задачи: «Вычислить значение выражения: ((2*c)-(d/3)) / (b-(a/4))»
textual
Листинг программы
;((2*c)-(d/3)) mov eax, c mov ebx, 2 imul ebx push eax push edx mov eax, d cdq mov ebx, 3 idiv ebx cdq pop ebx pop ecx sub ecx, eax sbb ebx, edx push ecx push ebx ;(b-(a/4)) mov eax, a cdq mov ebx, 4 idiv ebx mov ebx, b sub ebx, eax ;((2*c)-(d/3)) / (b-(a/4)) pop edx pop eax idiv ebx mov r, eax
Объяснение кода листинга программы
- Значение переменной
c
перемещается в регистр eax. - Значение переменной
2
перемещается в регистр ebx. - Производится умножение значений в регистрах eax (c) и ebx (2), результат сохраняется в edx и eax.
- Значение edx (старшая половина результата умножения) помещается в стек.
- Значение eax (младшая половина результата умножения) помещается в стек.
- Значение переменной
d
перемещается в регистр eax. - Расширение знака знакового числа в регистре eax до edx:eax (размещая старшую половину в edx и младшую половину в eax).
- Значение переменной
3
перемещается в регистр ebx. - Производится деление значений в edx:eax (d) на ebx (3), результат сохраняется в edx и eax.
- Расширение знака знакового числа в регистре eax до edx:eax (размещая старшую половину в edx и младшую половину в eax).
- Старшая половина результата умножения извлекается из стека и помещается в регистр ebx.
- Младшая половина результата умножения извлекается из стека и помещается в регистр ecx.
- Выполняется вычитание значения eax (результат деления d на 3) из значения ecx (его доминантная половина).
- Выполняется заимствование (borrow) значения edx (результата деления d на 3) из значения ebx (его резидуальная половина).
- Результат вычитания (полное число) помещается в стек.
- Значение переменной
a
перемещается в регистр eax. - Расширение знака знакового числа в регистре eax до edx:eax (размещая старшую половину в edx и младшую половину в eax).
- Значение переменной
4
перемещается в регистр ebx. - Производится деление значений в edx:eax (a) на ebx (4), результат сохраняется в edx и eax.
- Значение переменной
b
перемещается в регистр ebx. - Выполняется вычитание значения eax (результат деления a на 4) из значения ebx.
- Результат вычитания помещается в регистр ebx.
- Старшая половина результата умножения извлекается из стека и помещается в регистр edx.
- Младшая половина результата умножения извлекается из стека и помещается в регистр eax.
- Выполняется деление значения eax (результат операции ((2*c)-(d/3))) на значение ebx (результат операции (b-(a/4))).
- Результат деления сохраняется в переменную
r
.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д