Delphi汇编函数返回长字符串 [英] Delphi Assembly Function Returning a Long String

查看:242
本文介绍了Delphi汇编函数返回长字符串的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在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 应该保存结果字符串的地址。然后我分别将 edx ecx 设置为3和1252,然后调用 System。 _LStrSetLength 。实际上,我做

  _LStrSetLength(@result,3,1252)
/ pre>

其中3是字符串的新长度(以字符=字节),1252为标准 windows-1252 代码页。



然后,知道 eax 的地址字符串的第一个字符,我只需将字符串设置为ABC。但它不工作 - 它给我废话数据或EAccessViolation。有什么问题?



更新



现在我们有两个看似工作的 myfunc ,一个使用 NewAnsiString ,一个使用 LStrSetLength 。我不禁想到,如果两者都是正确的,在这个意义上,他们不会弄乱Delphi的内部处理字符串(引用计数,自动释放等)。

解决方案

你必须使用某种方式:

  function myfunc:AnsiString; 
asm
push eax // save @result
call system。@ LStrClr
mov eax,3 {Length}
{$ ifdef UNICODE}
mov edx,1252 // Delphi 2009/2010的代码页
{$ endif}
调用系统@ NewAnsiString
pop edx
mov [edx],eax
mov [eax] $ 303132
end;

它将返回一个'210'字符串...



在2009年之前,将{$ ifdef UNICODE}块放在您的代码与Delphi版本兼容之前,总是一个好主意。


I am trying to learn inline assembly programming in Delphi, and to this end I have found this article highly helpful.

Now I wish to write an assembly function returning a long string, specifically an AnsiString (for simplicity). I have written

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;

Explanation:

A function returning a string has an invisible var result: AnsiString (in this case) parameter, so, at the beginning of the function, eax should hold the address of the resulting string. I then set edx and ecx to 3 and 1252, respectively, and then call System._LStrSetLength. In effect, I do

  _LStrSetLength(@result, 3, 1252)

where 3 is the new length of the string (in characters = bytes) and 1252 is the standard windows-1252 codepage.

Then, knowing that eax is the address of the first character of the string, I simply set the string to "ABC". But it does not work - it gives me nonsense data or EAccessViolation. What is the problem?

Update

Now we have two seemingly working implementations of myfunc, one employing NewAnsiString and one employing LStrSetLength. I cannot help but wonder if both of them are correct, in the sense that they do not mess upp Delphi's internal handling of strings (reference counting, automatic freeing, etc.).

解决方案

You have to use some kind of:

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;

It will return a '210' string...

And it's always a good idea of putting a {$ifdef UNICODE} block to have your code compatible with version of Delphi prior to 2009.

这篇关于Delphi汇编函数返回长字符串的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆