ASM中调用函数的几个问题

okmnji79513 2009-03-05 11:11:42
加精

procedure FunTest(c:char);
begin
showmessage(c);
end;

procedure TForm1.FunTestA(i:integer);
begin
showmessage(inttostr(i));
end;

procedure TForm1.FunTestC;
begin
showmessage('FunTestC');
end;

procedure FunTestD(pc:PChar);
begin
showmessage(pc);
end;

(1):
begin
asm
call FunTestC
end;
end;

(2):
var p:pointer;
begin
p:=@FunTestC;
asm
call p
end;
end;

(3):
begin
asm
mov eax,$41
call FunTest
end;
end;

(4):
begin
asm
mov eax,$41
call FunTestA
end;
end;

(5):
var p:pointer;
begin
p:=@FunTestA;
asm
mov eax,$41
call p
end;
end;

(6):
var p:pointer;
begin
p:=@FunTestD;
asm
mov eax,$41
call p
end;
end;

如上,我在Delphi中写了一些函数,我用asm调用它们。
问题:
1、代码(1) 没问题。为何代码(2),会在p:=@FunTestC;处报:Variable required?
2、代码(3) 正常显示字符‘A’。为何代码(4)显示的不是65,而是一个很大的数字?

(即 参数没有传到)
3、代码(5) 应该怎么改?它也是在p:=@FunTestA;处报:Variable required。
4、如 代码(6) ,我要调用的函数的参数是字符串,应该怎么弄??(我用的

FunTestD参数是PChar,直接内存错误:其中有一句:Access violation at address

0040443F in module 'xxxx.exe'.Read of address 00000041 我传$41怎么变成读

0x00000041处的值了?)
...全文
1012 58 打赏 收藏 转发到动态 举报
写回复
用AI写文章
58 条回复
切换为时间正序
请发表友善的回复…
发表回复
boaoxbaobao 2009-03-09
  • 打赏
  • 举报
回复
高人呀!牛!
pearlina 2009-03-07
  • 打赏
  • 举报
回复
反正begin/end内嵌asm/end的话,如果在asm之前做了许多工作,那么具体哪个寄存器会被占用我也不好说。我很少直接写汇编,而且写的话也不爱在begin/end中内嵌,实在需要的话我也都是先看反汇编在asm前弄成什么样了然后再写
7年 2009-03-06
  • 打赏
  • 举报
回复
学习。
ph215405357 2009-03-06
  • 打赏
  • 举报
回复
jf
cht_1988 2009-03-06
  • 打赏
  • 举报
回复
来看看啊
Seamour 2009-03-05
  • 打赏
  • 举报
回复
你把你的代码贴全
procedure XXX.foo;
asm
end;

procedure foo;
asm
end;
的处理是不一样的,前者eax是Self指针
类的成员函数也和一般的函数指针不一样,procedure of object类型是8字节(System.TMethod),也就是两个指针。其中一个是实例地址或类地址,另一个是函数地址。成员函数是有方法按普通方法调用的,只是麻烦一点儿
bdmh 2009-03-05
  • 打赏
  • 举报
回复
FunTestD声明为系统级函数了吗
bdmh 2009-03-05
  • 打赏
  • 举报
回复

var
p:pointer;
pc:PChar;
begin
p:=@FunTestD;
pc:='Test'#0;
asm
push pc
mov eax,$41
call p
end;
end;
这个过程没错
okmnji79513 2009-03-05
  • 打赏
  • 举报
回复
问题4:写成这样 不行啊:

var p:pointer;
pc:PChar;
begin
p:=@FunTestD;
pc:='Test'#0;
asm
push pc
mov eax,$41
call p
end;
end;//还是这句内存错误:Access violation at address 0040443F in module 'xxxx.exe'.Read of address 00000041.




类方法是不能 asm call , 还是它比较难比较烦?
bdmh 2009-03-05
  • 打赏
  • 举报
回复
4、如 代码(6) ,我要调用的函数的参数是字符串,应该怎么弄??(

var
p:pointer;
Str : PChar;
begin
Str := 'abc'#0;
p:=@FunTestD;

asm
push Str;
mov eax,$41
call p
end;
end;
bdmh 2009-03-05
  • 打赏
  • 举报
回复
不要这么用,就用系统级函数

系统级别的, 不能是某个类(譬如: TForm1)的方法, 并且有严格的格式(参数、返回值)要求, 不管你暂时是不是需要都必须按格式来;
okmnji79513 2009-03-05
  • 打赏
  • 举报
回复
我调用FunTestA时,用

var p:pointer;
begin
p:=@form1.FunTestA; //报错:Variable required
asm
mov eax,$41
call p
end;
end;

var p:pointer;
begin
p:=@TForm1.FunTestA;
asm
mov eax,$41
call p
end;
end; //显示的不是65,而是一个很大的数字


怎么回事??
bdmh 2009-03-05
  • 打赏
  • 举报
回复
调用可以,但要指明函数的来源,比如form1.xxx
okmnji79513 2009-03-05
  • 打赏
  • 举报
回复
to dbmh兄

也就是说 类的函数 都不能用asm call来调用喽???

还有 看看问题4呢。谢谢
bdmh 2009-03-05
  • 打赏
  • 举报
回复

procedure FunTest(c:char);
begin
showmessage(c);
end;

procedure FunTestA(i:integer);
begin
showmessage(inttostr(i));
end;

procedure FunTestC;
begin
showmessage('FunTestC');
end;

procedure FunTestD(pc:PChar);
begin
showmessage(pc);
end;
bdmh 2009-03-05
  • 打赏
  • 举报
回复
2、代码(3) 正常显示字符‘A’。为何代码(4)显示的不是65,而是一个很大的数字?
这个问题和第一个问题一样,FunTestA改为系统函数
bdmh 2009-03-05
  • 打赏
  • 举报
回复
为何代码(2),会在p:=@FunTestC;处报:Variable required?
p:=@FunTestC;FunTestC是form1的,要声明为系统函数,和FunTest一样
liangpei2008 2009-03-05
  • 打赏
  • 举报
回复
学习
kyokusanagi98 2009-03-05
  • 打赏
  • 举报
回复
这样做到底行不行哟
canking007 2009-03-05
  • 打赏
  • 举报
回复
[Quote=引用 29 楼 jadeluo 的回复:]
补充一下上面的回帖, 当TForm1.FuncTestC函数申明为stdcall时, 需要push eax或push self, 否则不需要。
[/Quote]


是这样呀。
加载更多回复(34)

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧