Вычислить значение выражения: ((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
.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д