Delphi и ассемблерная вставка

Требуется вывести сумму элементов массива, стоящих на нечётных местах, с использование ассемблерной вставки Вот мой код:
program Project2;
 
{$APPTYPE CONSOLE}
 
uses
  SysUtils;
var
  a:array[0..6] of word;
  i, sum: word;
 
begin
  For i:=0 to 6 do
  begin
    Write('Vvedite a[',i+1,']: ');
    read(a[i]);
    Writeln;
  end;
  asm
    xor ax,ax
    xor bx,bx
    mov bx,0
    mov cx,7
  @lp1:
    add ax, word ptr a[bx]
    add bx,4
    loop @lp1
    mov sum,ax
  end;
  Write('Summa elementov, stoyashchih na nechetnyh mestax ',sum);
  Readln;
  readln;
end.
При дебаге вылетает ошибка на этой строчке
add ax, word ptr a[bx]
6 ответов

В качестве адреса надо указывать целый регистр.
program Project2;
 
{$APPTYPE CONSOLE}
 
uses
  SysUtils;
 
const
  n = 7;
var
  a:array[1..n] of word;
  i, sum: word;
 
begin
  For i:=1 to n do
  begin
    Write('Vvedite a[',i,']: ');
    read(a[i]);
    Writeln;
  end;
  asm
    xor ax, ax
    mov ecx, n
    shr ecx, 1
    jnc @1
    mov ax, word ptr a[ecx*4]
  @1:
    add ax, word ptr a[ecx*4-4]
    dec ecx
    jnz @1
    mov sum, ax
  end;
  Write('Summa elementov, stoyashchih na nechetnyh mestax ',sum);
  Readln;
  readln;
end.


Спасибо, а не могли бы вы объяснить эти строчки:
mov ax, word ptr a[ecx*4]
add ax, word ptr a[ecx*4-4]
Почему *4 и -4?


В квадратных скобках указывается смещение в байтах относительно первого эл-та массива. Каждый эл-т у нас занимает 2 байта (word), а нам нужны только нечетные, поэтому длинну массива делим пополам:
shr ecx, 1
если число эл-тов нечетное, то добавляем последний к результату:
mov ax, word ptr a[ecx*4]
т.е. 7 div 2 = 3, 3 * 2 * (размер эл-та) = 6, а[0] - это первый эл-т, следовательно а + 6 - получаем седьмой. -4 от седьмого - пятый далее уменьшаем счетчик на 1 и получаем: a[2 * 2 * 2 - 4] - третий эл-т, и т.д.


Немного побаловался с вашим кодом, в результате убрал несколько строк, без которых программа работает нормально:
program Project2;
 
{$APPTYPE CONSOLE}
 
uses
  SysUtils;
 
const
  n = 6;
var
  a:array[1..n] of word;
  i, sum: word;
 
begin
  For i:=1 to n do
  begin
    Write('Vvedite a[',i,']: ');
    read(a[i]);
    Writeln;
  end;
  asm
    xor ax, ax
    mov ecx, n
  @1:
    add ax, word ptr a[ecx*4-4]
    dec ecx
    jnz @1
    mov sum, ax
  end;
  Write('Summa elementov, stoyashchih na nechetnyh mestax ',sum);
  Readln;
  readln;
end.


программа работает нормально
Не может она работать нормально. Убедись сам - введи на нечетные места хотя бы пару чисел, больших чем 32768


У тебя идет обращение к памяти за пределами массива и не факт, что там всегда будут нули. Правильную работу такого кода гарантировать невозможно.