Domanda

Sto cercando di imparare la programmazione di assemblaggio in linea a Delphi, ea tal fine ho trovato Questo Articolo Altamente utile.

Ora Desidero scrivere una funzione di assemblaggio Restituzione di una stringa lunga, in particolare un AnsiString (per semplicità). Ho scritto

function myfunc: AnsiString;
asm
  // eax = @result
  mov edx, 3
  mov ecx, 1252
  call System.@LStrSetLength
  mov [eax + 0], ord('A')
  mov [eax + 1], ord('B')
  mov [eax + 2], ord('C')
end;
.

Spiegazione:

Una funzione Restituzione di una stringa ha un parametro var result: AnsiString invisibile (in questo caso), quindi, all'inizio della funzione, eax dovrebbe tenere l'indirizzo della stringa risultante. Ho quindi impostato edx e ecx a 3 e 1252, rispettivamente, quindi chiamare System._LStrSetLength. In effetti, lo faccio

  _LStrSetLength(@result, 3, 1252)
.

Dove 3 è la nuova lunghezza della stringa (in caratteri= bytes) e 1252 è lo standard windows-1252 codepage.

Allora, sapendo che eax è L'indirizzo del primo carattere della stringa , ho semplicemente impostato la stringa in "ABC". Ma non funziona - mi dà dati senza senso o eaccessviolation. Qual è il problema?

Aggiorna

Ora abbiamo due implementazioni apparentemente funzionanti di myfunc, uno che impiega NewAnsiString e uno che impiega LStrSetLength. Non posso fare a meno di chiedermi se entrambi sono corretti, nel senso che non mettono incasinare la movimentazione interna delphi di stringhe (conteggio di riferimento, liberazione automatica, ecc.).

È stato utile?

Soluzione

Devi usare un po 'di:

function myfunc: AnsiString;
asm
  push eax // save @result
  call system.@LStrClr
  mov    eax,3                 {Length}
{$ifdef UNICODE}
  mov    edx,1252 // code page for Delphi 2009/2010
{$endif}
  call   system.@NewAnsiString
  pop edx
  mov [edx],eax
  mov [eax],$303132
end;
.

restituirà una stringa "210" ...

Ed è sempre una buona idea di mettere un blocco {$ IFDEF Unicode} per avere il tuo codice compatibile con la versione di Delphi prima del 2009.

Altri suggerimenti

Con l'eccellente aiuto di A.bouchez, sono riuscito a correggere il mio codice, impiegando LStrSetLength:

function myfunc: AnsiString;
asm

  push eax

  // eax = @result
  mov edx, 3
  mov ecx, 1252
  call System.@LStrSetLength

  pop eax

  mov ecx, [eax]

  mov [ecx], 'A'
  mov [ecx] + 1, 'B'
  mov [ecx] + 2, 'C'

end;
.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top