Помогите , пожалуйста, с ассемблером в программе турбо паскаль

не могу правильно написать программу, а точнее поделить

var
s:word;
c:integer;
begin
writeln('найти сумму s=x^3/2+1 при x[0,40]');
asm
mov cx, 2
mov dx, 0
mov bx, 0
@1:
add dl, 1
mov al, dl
mul dl
mul dl
mov bl, dl
mov bl, 2
div bl
add ax, 1
add bx,ax
loop @1
mov s, bx
end;
writeln ('s:= ',s);
end.

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

Автор решения: Anton Shchyrov
mov cx, 2

Записали в cx 2

mul dl

умножили AL на DL, результат положили в AX

mul dl

опять умножили AL на DL, результат положили в AX, то что было в AH потеряли

mov bl, dl
mov bl, 2

вначале в BL записали значение DL, потом записали в BL 2. Вопрос - зачем записывали DL?

loop @1

уменьшили значение CX, и если оно не стало равно нулю, то начали еще одну итерацию. Вопрос, сколько у нас выполнится итераций, если вы вначале выполнили mov cx, 2?

Далее, общее замечание, в ассемблерных вставках вы можете свободно модифицировать три регистра AX, CX, DX. Значение остальных регистров, если вы их модифицируете, нужно восстановить.

Теперь правильный код.

function sum: Word; assembler;
asm
  push bx     { сохраним регистр bx }
  xor bx, bx  { обнулили регистр bx. Здесь будем собирать итоговую сумму }
  mov cx, 40  { записали в cx, количество итераций. Одновременно это будет текущее значение x }
@1:
  mov ax, cx
  mul cx      { умножаем ax на cx. Результат будет в паре dx:ax. Но для X <= 40 нам хватит и 2 байт }
  mul cx
  shr ax, 1   { сдвигаем ax на один бит вправо, что эквивалентно делению на 2 }
  inc ax      { добавляем к ax 1 }
  add bx, ax  { суммируем с аккумулятором }
  loop @1     { уменьшили значение cx, и если оно не стало равно нулю, то начали еще одну итерацию }
  inc bx      { мы пропустили итерацию при x = 0. Добавляем значение 0^3/2+1=1 }
  mov ax, bx  { результат функции возвращаем через ax }
  pop bx      { восстанавливаем значение bx }
end;

begin
  writeln ('s:= ', sum);
end.
→ Ссылка