使用函数指针的问题

procedure TForm1.Button1Click(Sender: TObject);
var
  a, b, c: Integer;
  xxx: procedure;

  procedure AddAToC;
  begin
    Inc(c, a);
    ShowMessage('AddAToC: Inc(c, a) = ' + IntToStr(c));
  end;

  procedure AddBToC;
  begin
    Inc(c, b);
    ShowMessage('AddBToC: Inc(c, b) = ' + IntToStr(c));
  end;

begin
  a := 1;
  b := 2;
  c := 3;

  xxx := @AddAToC;
  xxx;      //调用 AddAToC, 应该弹出 AddAToC: Inc(c, a) = 4
  xxx := @AddBToC;
  xxx;    //调用 AddAToC, 应该弹出 AddAToC: Inc(c, a) = 5

  ShowMessage(IntToStr(c));

  AddAToC;
  AddBToC;

  ShowMessage(IntToStr(c));
end;
运行了一下,的确很奇怪
xxx;的时候应该是 AddAToC: Inc(c,a) = 4;
结果弹出来的却是:AddAToC:Inc(c,a) = 4566634;
在CPUwindow跟踪了一下,发现问题了。
Unit1.pas.45: a := 1;
0045E041 C745FC01000000   mov [ebp-$04],$00000001
Unit1.pas.46: b := 2;
0045E048 C745F402000000   mov [ebp-$0c],$00000002
Unit1.pas.47: c := 3;
0045E04F C745F803000000   mov [ebp-$08],$00000003
这里可以看到 1,2,3分别被放到[ebp-$04],[ebp-$0c],[ebp-$08]这些地方。
这个时候ebp=$12f608.
继续往下走,来到调用XXX的地方。
Unit1.pas.49: xxx := @AddAToC;
0045E056 B804DF4500       mov eax,$0045df04
Unit1.pas.50: xxx;
0045E05B 8BD8             mov ebx,eax
0045E05D FFD3             call ebx  <-----这里开始调用xxx。
F7单步进去:
Unit1.pas.34: Inc(c, a);
0045DF19 8B4508           mov eax,[ebp+$08] <-----这一步ebp已经变化了,
0045DF1C 8B40FC           mov eax,[eax-$04]
0045DF1F 8B5508           mov edx,[ebp+$08]
0045DF22 0142F8           add [edx-$08],eax
Unit1.pas.35: ShowMessage('AddAToC: Inc(c, a) = ' + IntToStr(c));
我的看法是,因为你直接调用的是函数指针,因此没能正常识别内层函数和外层函数在栈上
分配的局部变量。而正常调用因为有正常的保护,所以没有问题。
如果把a,b,c申明为全局变量,就正常了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值