質問

私はDelphiでインラインアセンブリプログラミングを学ぼうとしています、そしてこの終わりに私はこれを見つけました。記事非常に役に立つ。

今、長文字列、特にAnsiString(簡単にするために)を返すアセンブリ関数を書きたい。私は

を書いた
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;
.

説明:

文字列を返す関数には、非表示になっているvar result: AnsiString(この場合)がありますので、関数の先頭では、eaxは結果の文字列のアドレスを保持する必要があります。その後、edxecxをそれぞれ3および1252に設定してから、System._LStrSetLengthを呼び出します。事実上、私は

をしています
  _LStrSetLength(@result, 3, 1252)
.

3は文字列の長さ(文字=バイト)、1252は標準 Windows-1252 コードページ。

それでは、eax文字列の最初の文字のアドレスを知っていることを知っています。 a>、私は単に文字列を "abc"に設定します。しかし、それはうまくいきません - それは私に無意味なデータやeaccessviolationを与えます。問題は何ですか?

更新

今我々は、myfuncを採用している1つ、NewAnsiStringLStrSetLengthを使用するものを使用している2つの一見作業実装を持っています。 UPP Delphiの弦の内部取り扱い(参照カウント、自動解放など)を混乱させないという意味で、それらの両方が正しいかどうかを助けることはできません。

役に立ちましたか?

解決

何らかの種類のものを使わなければなりません:

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;
.

'210'文字列を返します...

そして2009年の{$ ifdef Unicode}ブロックを{$ ifdef Unicode}ブロックを入れることの良い考えです。

他のヒント

A.Bouchezの優れた援助で、私は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;
.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top