解一段asm汇编代码的function(100分)

  • 主题发起人 主题发起人 moonight
  • 开始时间 开始时间
M

moonight

Unregistered / Unconfirmed
GUEST, unregistred user!
function DelphiString(str: string): Integer;
asm
mov ecx, [eax-4]
mov result, ecx
end;
当你调用DelphiString('abc')的时候,函数返回值为( ),为什么?

================================
补充:
---------
我想再次强调,不要说运行不起,这是一道权威的题目,我只是想知道这个题所返回的值是怎么来的。

我自己先分析了一下:
这道题,放到程序里面(本来要求是脱离IDE环境回答的)测试,结果表明返回值是传入的String的字符串长度。
那么两行汇编代码怎么就可以得到传入参数的长度?是不是与String类型在内存里的存储有关?

现在就是这个问题没搞懂,欢迎各位进来研究。关键在于回答问题中的“为什么”!

灌 水 就 免 了 !!!
 
将这段代码写在程序里面测试一下就知道了撒.
 
function DelphiString(str: string): Integer;
begin
asm
mov ecx, [eax-4]
mov result, ecx
end;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
//
showmessage(inttostr(delphistring('abc')));
end;
这个代码运行不起,要出错,哈哈.
 
我想应该是字符串的引用计数
 
必须是 long string 类型才行
 
这跟string数据类型的存储结构有关,具体是什么结构请参考Delphi的Help,里面有详细的解释--就在“Long strings”那个主题里面,自己搜索一下就找到了。其实关键就一段话:
=====================================================
A long-string variable is a pointer occupying four bytes of memory. When the variable is empty--that is, when it contains a zero-length string--the pointer is nil and the string uses no additional storage. When the variable is nonempty, it points a dynamically allocated block of memory that contains the string value. The eight bytes before the location contain a 32-bit length indicator and a 32-bit reference count. This memory is allocated on the heap, but its management is entirely automatic and requires no user code.
======================================================

根据这个原理,还可以写一个更简单的返回字符串长度的函数:
procedure TForm1.Button1Click(Sender: TObject);

function DelphiString(str: string): Integer;
asm
mov ecx, [eax-4]
mov result, ecx
end;

function StringLength(str: string): integer;
begin
Result:=PInteger(Integer(Pointer(str))-4)^
end;

begin
showmessage(inttostr(DelphiString(Edit1.Text)));
showmessage(inttostr(StringLength(Edit1.Text)))
end;

end.
 
简单说string类型实际是一个指针
这个指针的前四个字节就是这个string的长度
指针指向的就是字符串的数据
方便和PChar转换,可以估计:
这个指针的最后还的加上一个#0结束
一个string至少要占用SizeOf(Integer)+Length(S)+SizeOf(Char)内存
官方并不保证以后存储方式不会发生改变
那段Asm和如下语句到达一样的效果
function DelphiString(str: string): Integer;
begin
Result := PInteger(Integer(str) - SizeOf(Integer))^;
end;
 
感谢韦剑,看来我还得多看看帮助啊,不过英文读起来的确要吃力一些。
 
也感谢后来的zswang,不过分数已经给出去了,不好意思
 
后退
顶部