devels писал(а):Чем вас не устраивает обычный Length ? Или он медленнее?
Тем, что я вообще не хотел вызывать процедуру Length в своем асм коде... она просто лишняя, и думал справится простым обращением через смещение -4. для динамического массива.
Но получается, что так нельзя делать, если данный код будет находится в ДЛЛ и работать с динамичискими массивами, которы будут создаваться в другом языке отличным от Free Pascal.
Пример:
DLL в которой одна функция суммирующая элементы массива:- Код: Выделить всё
- library ASMDinArray;
 
 {$mode objfpc}{$H+}
 
 uses
 Classes
 { you can add units after this };
 
 type
 TIntArray2 = array  of integer;
 
 
 {$R *.res}
 
 function Sum1(var A:TIntArray2):Integer;Register;assembler;
 {$ASMMODE intel}
 asm
 mov EAX,[EAX]
 mov ECX,[EAX-4]
 //dec ECX
 mov EDX,[EAX]
 @Summ:
 add EAX,4
 add EDX,[EAX]
 loop @Summ
 mov EAX,EDX
 end;
 
 Exports
 Sum1 index 1;
 begin
 end.
Вызываем ее в программе написанной на Lazarus:- Код: Выделить всё
- unit Unit1; 
 
 {$mode objfpc}
 //{$MODE DELPHI}
 {$H+}
 
 interface
 
 uses
 Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls;
 
 type
 
 { TForm1 }
 
 TForm1 = class(TForm)
 Button1: TButton;
 Button2: TButton;
 Memo1: TMemo;
 procedure Button2Click(Sender: TObject);
 private
 { private declarations }
 public
 { public declarations }
 end;
 
 TIntArray2 = array  of integer;
 var
 Form1: TForm1;
 
 implementation
 function Sum1(var A:TIntArray2):Integer;Register;  External 'project2.dll';
 
 {$R *.lfm}
 
 { TForm1 }
 
 procedure TForm1.Button2Click(Sender: TObject);
 var D1:TIntArray2;
 begin
 SetLength(D1,3);
 D1[0]:=1;
 D1[1]:=2;
 D1[2]:=3;
 caption:=IntToStr(Sum1(D1));
 end;
 end.
 
Тестируем, видим что отработали хорошо, в название формы вернули число 6;
Теперь хотим использовать данную Dll 
в программе написанной на Delphi:- Код: Выделить всё
- unit Unit1;
 
 interface
 
 uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs, StdCtrls;
 
 type
 TForm1 = class(TForm)
 Button1: TButton;
 procedure Button1Click(Sender: TObject);
 private
 { Private declarations }
 public
 { Public declarations }
 end;
 
 TIntArray2 = array  of integer;
 
 var
 Form1: TForm1;
 
 implementation
 
 {$R *.dfm}
 function Sum1(var A:TIntArray2):Integer;Register;  External 'project2.dll';
 
 
 procedure TForm1.Button1Click(Sender: TObject);
 var D1:TIntArray2;
 begin
 SetLength(D1,3);
 D1[0]:=1;
 D1[1]:=2;
 D1[2]:=3;
 
 caption:=IntToStr(Sum1(D1));
 
 end;
 end.
 
Видим вернули чушь. А все потому что FPC и Delphi генерируют в памяти динаммические массивы один в один, 
кроме поля Length. по смещение -4 относительно указателя (переменной) массива.
Тобишь чтобы библиотека работала вместе с Делфи, нужно ее переписать вот так:
- Код: Выделить всё
-  function Sum1(var A:TIntArray2):Integer;Register;assembler;
 {$ASMMODE intel}
 asm
 mov EAX,[EAX]
 mov ECX,[EAX-4]
 dec ECX
 mov EDX,[EAX]
 @Summ:
 add EAX,4
 add EDX,[EAX]
 loop @Summ
 mov EAX,EDX
 end;
 
Добавили вот это:- Код: Выделить всё
- dec ECX
Потому что эти поля отличаются на еденицу....
Вот это меня и возмутило, я думал что это Бага, но 
Sergei I. Gorelkin, говорит, что это принципиально так сделано (я предпологаю, что из за того, что считается мол процедура High используется наиболее часто).
Поэтому я не могу так писать, используя поле Length, для использования библиотеки как в FPC так и в Delphi. 

 Вот это меня и растраивает  
 
 Выход, либо внутри блока Asm вызывать процедуру Length, чего не хотелось... 

А использование директивы Delphi mode, ничего не меняет, FPC все равно генерит для поля Length не длину массива, а максимальный элемент тобишь High.