很简单的代码,怎么就是调试通不过呢(50分)

  • 主题发起人 主题发起人 wp231957
  • 开始时间 开始时间
W

wp231957

Unregistered / Unconfirmed
GUEST, unregistred user!
function tform1.showm(a:pchar):boolean;  //注意这里函数随便,用哪个函数都可以,只是为了说明问题而已 <br>begin<br> &nbsp;messagebox(0,a,nil,mb_ok);<br> &nbsp;result:=true;<br>end;<br>procedure TForm1.Button7Click(Sender: TObject);<br>var<br> &nbsp;func:pointer;<br> &nbsp;addr:pchar;<br>begin<br> &nbsp;addr:='afsda';<br> &nbsp;func:=@tform1.showm;  //这里一定要用取函数地址的方式<br> &nbsp;asm<br> &nbsp; &nbsp;push addr<br> &nbsp; &nbsp;call func         //这里一定要用ASM 的CALL方式来调用函数<br> &nbsp;end;<br>end;
 
你的说说你要干什么
 
忘了写<br>begin 了吧 &nbsp;我们连问题也没看到
 
function tform1.showm(a:pchar):boolean;  <br>begin<br> &nbsp;messagebox(0,a,nil,mb_ok);<br> &nbsp;result:=true;<br>end;<br>procedure TForm1.Button7Click(Sender: TObject);<br>var<br> &nbsp;func:pointer;<br> &nbsp;addr:pchar;<br>begin<br> &nbsp;addr:='afsda';<br> &nbsp;func:=@tform1.showm;  //这里一定要用取函数地址的方式<br> &nbsp;asm<br> &nbsp; &nbsp;push addr<br> &nbsp; &nbsp;call func         //这里一定要用ASM 的CALL方式来调用函数<br> &nbsp;end;<br>end; &nbsp;<br>我想做的一件事就是使用ASM的CALL来调用某个函数<br>先PUSH几个合法的参数,然后CALL之,不知道为什么运行错误
 
来自:nihg, 时间:2006-6-25 14:59:21, ID:3480881<br>忘了写<br>begin 了吧 &nbsp;我们连问题也没看到 &nbsp;<br><br>不会的,因为编译是可以通过的,只不过运行错误而已
 
tform1.showm &nbsp; 注意到了没有,是个类方法。<br>故除了你能看到的参数,还需要传递this指针(标识tform1),你可看看一般的反汇编书籍。
 
来自:smallstomach, 时间:2006-6-25 15:04:21, ID:3480887<br>tform1.showm &nbsp; 注意到了没有,是个类方法。<br>故除了你能看到的参数,还需要传递this指针(标识tform1),你可看看一般的反汇编书籍。 &nbsp;<br><br>我把TFORM1.去掉也不可以(就是做成一个独立的函数)<br>同样是运行错误
 
function showm(a:pchar):boolean;//注意这里函数随便,用哪个函数都可以,只是为了说明问题而已 <br>begin<br> &nbsp;messagebox(0,a,nil,mb_ok);<br> &nbsp;result:=true;<br>end;<br>procedure TForm1.Button7Click(Sender: TObject);<br>var<br> &nbsp;func:pointer;<br> &nbsp;addr:pchar;<br>begin<br> &nbsp;addr:='afsda';<br> &nbsp;func:=@showm;//这里一定要用取函数地址的方式<br> &nbsp;asm<br> &nbsp; &nbsp;push addr<br> &nbsp; &nbsp;call func//这里一定要用ASM 的CALL方式来调用函数<br> &nbsp; &nbsp;add sp,4<br> &nbsp;end;<br>end;<br><br>end.<br><br><br><br><br><br><br>不行吗
 
来自:smallstomach, 时间:2006-6-25 15:16:09, ID:3480890<br><br>能告诉我ADD SP, 4 是干什么的吗
 
因为你的这一个语句导致结果正确
 
这就是把你刚才入栈的addr清除掉,
 
再来:<br>function showm(a:pchar;b:pchar):boolean;<br>begin<br> &nbsp;messagebox(0,a,b,mb_ok);<br> &nbsp;result:=true;<br>end;<br>procedure TForm1.Button7Click(Sender: TObject);<br>var<br> &nbsp;func:pointer;<br> &nbsp;addr,addr2:pchar;<br>begin<br> &nbsp;addr:='这里是乱码';<br> &nbsp;addr2:='这里则正常';<br> &nbsp;func:=@showm;<br> &nbsp;asm<br> &nbsp; &nbsp;push addr<br> &nbsp; &nbsp;push addr2<br> &nbsp; &nbsp;call func<br> &nbsp; &nbsp;add sp,8<br> &nbsp;end;<br>end;
 
function showm(a:pchar):boolean;//注意这里函数随便,用哪个函数都可以,只是为了说明问题而已 <br>begin<br> &nbsp;messagebox(0,a,nil,mb_ok);<br> &nbsp;result:=true;<br>end;<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>var<br> &nbsp;func:pointer;<br> &nbsp;addr:pchar;<br>begin<br> &nbsp;addr:='afsda';<br> &nbsp;func:=@showm;//这里一定要用取函数地址的方式<br> &nbsp;asm<br> &nbsp; &nbsp;push addr<br> &nbsp; &nbsp;call func//这里一定要用ASM 的CALL方式来调用函数<br> &nbsp; &nbsp;[red]pop addr[/red]<br> &nbsp;end;<br>end;
 
什么意思,这不跟调用了一次addr2一样吗,当然没有任何错误。因为sp是加了8。所以button7Click仍能正确的找到返回地址。
 
来自:smallstomach, 时间:2006-6-25 15:31:17, ID:3480901<br>什么意思,这不跟调用了一次addr2一样吗,当然没有任何错误。因为sp是加了8。所以button7Click仍能正确的找到返回地址。 &nbsp;<br><br><br>function showm(a:pchar;b:pchar):boolean;<br>该函数有2个参数<br>不是需要把2个参数分别PUSH然后才能CALL吗???
 
function showm(a:pchar;b:pchar):boolean;[red]stdcall;[/red]<br>begin<br> &nbsp;messagebox(0,a,b,mb_ok);<br> &nbsp;result:=true;<br>end;<br><br>procedure TForm1.Button1Click(Sender: TObject);<br>var<br> &nbsp;func:pointer;<br> &nbsp;addr,addr2:pchar;<br>begin<br> &nbsp;addr:='这里是乱码';<br> &nbsp;addr2:='这里则正常';<br> &nbsp;func:=@showm;<br> &nbsp;asm<br> &nbsp; &nbsp;push addr<br> &nbsp; &nbsp;push addr2<br> &nbsp; &nbsp;call func<br> &nbsp; &nbsp;pop addr2<br> &nbsp; &nbsp;pop addr<br> &nbsp;end;<br>end;
 
噢,刚才没看见你把参数变成两个了。
 
感谢2位的帮助,OK了
 
这里有两个关键的细节,就是调用协议和你要调用的是一个类里面的函数。<br><br>关用默认调用约定DELPHI帮助文件里说了, 默认是通过寄存器的!<br>Calling conventions determine the order in which parameters are passed to the routine. They also affect the removal of parameters from the stack, the use of registers for passing parameters, and error and exception handling. [red]The default calling convention is register.[/red]<br>一般我们用汇编都用 寄存器 调用约定,所以把你要调用的函数声明为stdcall,这样被调用的函数负责平衡堆栈。<br><br>之后就是Self指针的问题, 因为你要调用的是一个类里的函数,根据反汇编得知,Self指针是第一个参数,而调用约定为stdcall,所以Self指针最后push<br><br>现面是代码<br>把要调用的函数定义在Form2<br> &nbsp; &nbsp;function Test(Msg: PChar): Integer; stdcall;<br><br>function TForm2.Test(Msg: PChar): Integer;<br>begin<br> &nbsp;MessageBox(0, Msg, Msg, MB_OK);<br> &nbsp;result:= 1;<br>end;<br><br>调用代码<br>var<br> &nbsp;Msg: PChar;<br>begin<br> &nbsp;Msg:= 'Hello!';<br> &nbsp;asm<br> &nbsp; &nbsp;push Msg<br> &nbsp; &nbsp;push Form2 &nbsp;//这里不能直接Push Self, 因为这里的Self是Form2<br> &nbsp; &nbsp;call TForm2.Test<br> &nbsp;end;<br><br>希望派分时多派点[:D]
 
后退
顶部