Параметр массив для asm функции[Решено]

Форум для изучающих FPC и их учителей.

Модератор: Модераторы

Параметр массив для asm функции[Решено]

Сообщение Maxizar » 03.03.2011 15:17:19

Есть такой тип данных:
Код: Выделить всё
  TIntArray = array of integer;


Проводим маленький тест:
Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
var D1:TIntArray;
     i:Integer;
begin
    SetLength(D1,5);
    CreateAr(D1);
    D1[0]:=1;
   for i:=0 to High(D1) do
   memo1.Lines.Add(IntToStr(D1[I]));
end;


где CreateAr(D1); это процедура такого вида:
Код: Выделить всё
procedure CreateAr(var D:TIntArray); register;assembler;
  {$ASMMODE intel}
  asm
  mov ECX,12
  mov dword ptr [EAX+8],ECX
  end;


Пробовал и просто так:
Код: Выделить всё
mov [EAX+8],ECX

Вывод в мемо выглядит все равно так:
Код: Выделить всё
1
0
0
0
0

Ведь мы перадали параметр как Var тобишь передали указатель на массив.
[EAX+8] говорит чтоб мы обратились к памяти по этому адресу, но что то я сделал не так.
Где, я заблудился?..
Последний раз редактировалось Maxizar 03.03.2011 15:45:24, всего редактировалось 1 раз.
Maxizar
постоялец
 
Сообщения: 385
Зарегистрирован: 20.03.2010 19:48:14

Re: Параметр массив для asm функции

Сообщение скалогрыз » 03.03.2011 15:21:08

наверное, потому-что массив динамический, который сам по себе указатель на хитрую структуру.

попробуй так:
Код: Выделить всё
TIntArray = array [0..4] of integer;
скалогрыз
долгожитель
 
Сообщения: 1803
Зарегистрирован: 03.09.2008 02:36:48

Re: Параметр массив для asm функции

Сообщение Maxizar » 03.03.2011 15:45:04

скалогрыз Спасибо...
Код: Выделить всё
TIntArray = array [0..4] of integer;

Данный метод не пойдет.. нужно как раз для динамических.. но благодаря фразе:
скалогрыз писал(а):наверное, потому-что массив динамический, который сам по себе указатель на хитрую структуру.

Вы мне открыли глаза... я сам же и забыл что динамический массив это указатель не на первый элемент а именно указатель.. а вот туда куда указывает этот указатель лежит указатель на первый элемент... :D ... Бывает и такое :oops:
Теперь все работает:
Код: Выделить всё
   TIntArray1 = array [0..4] of integer;
   TIntArray2 = array  of integer;

Тест и функции для типа: TIntArray1
Асм процедура
Код: Выделить всё
procedure CreateAr1(var D:TIntArray1); register;assembler;
  {$ASMMODE intel}
  asm
  mov dword ptr[EAX],0
  mov dword ptr[EAX+4],1
  mov dword ptr[EAX+8],2
  end;   

Тест:
Код: Выделить всё
procedure TForm1.Button1Click(Sender: TObject);
var D1:TIntArray1;
     i:Integer;
begin
    CreateAr1(D1);
   for i:=0 to High(D1) do
   memo1.Lines.Add(IntToStr(D1[I]));
end;

Тест и функции для типа: TIntArray2
Асм процедура
Код: Выделить всё
procedure CreateAr2(var D:TIntArray2); register;assembler;
{$ASMMODE intel}
asm
//push EBX
mov ECX,[EAX]
mov dword ptr[ECX],0
mov dword ptr[ECX+4],1
mov dword ptr[ECX+8],2
mov dword ptr[ECX+12],3
end;

Т.е мы сохраняем в ECX значение ячейки памяти на которую указывает (указатель динамического массива)
И тепрь ECX и есть память с которой расположен первый элемент...
Тест:
Код: Выделить всё
procedure TForm1.Button2Click(Sender: TObject);
var D1:TIntArray2;
     i:Integer;
begin
    SetLength(D1,5);
    CreateAr2(D1);
   for i:=0 to High(D1) do
   memo1.Lines.Add(IntToStr(D1[I]));
end;     


PS. Всем Спасибо :)
Maxizar
постоялец
 
Сообщения: 385
Зарегистрирован: 20.03.2010 19:48:14


Вернуться в Обучение Free Pascal

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 23

Рейтинг@Mail.ru