Вычислить значение выражения: ((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
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;
Сама ошибка - [Error] Unit1.pas(58): Operand size mismatch , выводится на mov c,bl , видимо ошибся в регистрах где-то, прошу указать на ошибку и подсказать как мне вывести значение, выводится в Edit1. Так же готов выслушать советы по оптимизации, возможно где-то сделал лишние операции.

Решение задачи: «Вычислить значение выражения: ((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

Объяснение кода листинга программы

  1. Значение переменной c перемещается в регистр eax.
  2. Значение переменной 2 перемещается в регистр ebx.
  3. Производится умножение значений в регистрах eax (c) и ebx (2), результат сохраняется в edx и eax.
  4. Значение edx (старшая половина результата умножения) помещается в стек.
  5. Значение eax (младшая половина результата умножения) помещается в стек.
  6. Значение переменной d перемещается в регистр eax.
  7. Расширение знака знакового числа в регистре eax до edx:eax (размещая старшую половину в edx и младшую половину в eax).
  8. Значение переменной 3 перемещается в регистр ebx.
  9. Производится деление значений в edx:eax (d) на ebx (3), результат сохраняется в edx и eax.
  10. Расширение знака знакового числа в регистре eax до edx:eax (размещая старшую половину в edx и младшую половину в eax).
  11. Старшая половина результата умножения извлекается из стека и помещается в регистр ebx.
  12. Младшая половина результата умножения извлекается из стека и помещается в регистр ecx.
  13. Выполняется вычитание значения eax (результат деления d на 3) из значения ecx (его доминантная половина).
  14. Выполняется заимствование (borrow) значения edx (результата деления d на 3) из значения ebx (его резидуальная половина).
  15. Результат вычитания (полное число) помещается в стек.
  16. Значение переменной a перемещается в регистр eax.
  17. Расширение знака знакового числа в регистре eax до edx:eax (размещая старшую половину в edx и младшую половину в eax).
  18. Значение переменной 4 перемещается в регистр ebx.
  19. Производится деление значений в edx:eax (a) на ebx (4), результат сохраняется в edx и eax.
  20. Значение переменной b перемещается в регистр ebx.
  21. Выполняется вычитание значения eax (результат деления a на 4) из значения ebx.
  22. Результат вычитания помещается в регистр ebx.
  23. Старшая половина результата умножения извлекается из стека и помещается в регистр edx.
  24. Младшая половина результата умножения извлекается из стека и помещается в регистр eax.
  25. Выполняется деление значения eax (результат операции ((2*c)-(d/3))) на значение ebx (результат операции (b-(a/4))).
  26. Результат деления сохраняется в переменную r.

Оцени полезность:

13   голосов , оценка 4.077 из 5