delphi - Inline asm (32) emulation of move (copy memory) command -


i have 2 two-dimensional arrays dynamic sizes (guess that's proper wording). copy content of first 1 other using:

    dest:=copy(src,0,4*x*y);     // src,dest:array of array of longint; x,y:longint;     // setlength(both arrays,x,y);  //x , y max 15 bit positive! 

it works. i'm unable reproduce in asm. tried following variations no avail... enlighten me...

    mov esi,src; mov edi,dest; mov ebx,y; mov eax,x; mul ebx;      push ds; pop es; mov ecx,eax; cld; rep movsd; 

also tried lea (didn't expect work since should fetch pointer address not array address), no workie, , tried with:

    p1:=@src[0,0]; p2:=@dest[0,0]; //being no-type pointers     mov esi,p1; mov edi,p2... (the same asm) 

hints pls? btw it's delphi 6. error is, of course, access violation.

this two-fold three-fold question.

  1. what's structure of dynamic array.

  2. which instructions in asm copy array.

  3. i'm throwing random assembler @ cpu, why doesn't work?

structure of dynamic array
see: http://docwiki.embarcadero.com/radstudio/seattle/en/internal_data_formats quote:

dynamic array types

on 32-bit platform, dynamic-array variable occupies 4 bytes of memory (and 8 bytes on 64-bit) contain pointer dynamically allocated array. when variable empty (uninitialized) or holds zero-length array, pointer nil , no dynamic memory associated variable. nonempty array, variable points dynamically allocated block of memory contains array in addition 32-bit (64-bit on win64) length indicator , 32-bit reference count. table below shows layout of dynamic-array memory block.

dynamic array memory layout (32-bit , 64-bit)

offset 32-bit    -8       -4       0  offset 64-bit   -12       -8       0 contents      refcount  count    start of data    

so dynamic array variable pointer middle of above structure.

how access in asm

let's assume array holds records of type tmyrec

you'll need run code every inner array in outer array deep copy. leave exercise reader. (you can other part in pascal).

type   tdynarr: array of tmyrec;  procedure slowbutbasicmove(const source: tdynarr; var dest); asm   //insert register pushes, see below.   mov esi,source          //esi = pointer source data   mov edi,dest            //edi = pointer dest   sub esi,8                  mov ebx,[esi]           //ebx = refcount (just in case)   mov ecx,[esi+4]         //ecx = element count   mov edx,sizeof(tmyrec)  //anywhere 1 zillions   mul ecx,edx             //==ecx=number of bytes in array.   //// can start moving    xor ebx,ebx             //ebx =0   add eax,8               //eax = @data   @loop:   mov eax,[esi+ebx]       //get data source   mov [edi+ebx],esi       //copy dest   add ebx,4               //4 bytes @ time   cmp ebx,ecx             //is ebx> number of bytes?   jle loop    //done copying.   //insert register pops, see below end; 

that's copy done, in order system not crash, need save , restore non volatile registers (all eax, ecx, edx), see: http://docwiki.embarcadero.com/radstudio/seattle/en/program_control

push ebx push esi push edi --- insert code shown above //restore non-volatile registers pop edi pop esi pop ebx  //note restoring must happen in reverse order of push. 

see jeff dunteman's book assembly step step if you're new asm.

you access violations if:

  • you try read wrong address.
  • you try write wrong adress.
  • you read past end of array.
  • you write memory haven't claimed before using getmem or whatever means.
  • if write past end of buffer.
  • if not restore non-volatile registers

remember you're directly dealing cpu. delphi not assist in way.

really fast code use form of sse move 16bytes per instruction in unrolled loop, see above mentioned fastcode examples of optimized assembler.

random assembler
in assembler need know exactly you're do, how , cpu does.
set breakpoint , run code. press ctrl + alt + c , behold cpu-debug window.
allow see code delphi generates.
can single step through code see cpu does.
see: http://www.plantation-productions.com/webster/index.html
more reading.


Comments

Popular posts from this blog

java - Suppress Jboss version details from HTTP error response -

gridview - Yii2 DataPorivider $totalSum for a column -

Sass watch command compiles .scss files before full sftp upload -