首页
社区
课程
招聘
[旧帖] 实参入栈过程[求助] 0.00雪花
发表于: 2010-4-30 17:44 1460

[旧帖] 实参入栈过程[求助] 0.00雪花

2010-4-30 17:44
1460
C++调用汇编中的一个过程,并传递三个参数
c++中声明如下:
extern "C" int __stdcall test(char *p,  char *q, char *r);
....
addr=test(p,q,r); //p, q, r 是三个数组名
printf("addr=%08x, p=%08x, q=%08x, r=%08x\n", addr, p ,q, r);

汇编部分代码:
   ...
   PUSH EBP
    MOV EBP ,ESP
    MOV EAX, [EBP+12]   ;EAX值应该是q,但结果是p
    ....
    POP EBP

编译执行后,C++中addr的值与p的值相同
我也测试了下其他的偏移地址
[EBP+12]   =   p
[EBP+16]   =   q
[EBP+20]   =   r

这是怎么回事啊?
首先说下我的理解, c++ 中调用test时,先push r, push q, push p, 然后再push返回的指令地址(应该是EIP吧,4个字节),进入汇编test过程后,先push ebp进行保存,然后ebp指向原先的ebp内容。我期待的结果是:  p=[ebp+8], q=[ebp+12], r=[ebp+16]

希望大家解决我的疑问.谢谢。

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (6)
雪    币: 128
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
__cdecl 是你理解那种, __stdcall 恰好相反, 就是你看到的pqr这个入栈顺序
2010-4-30 17:51
0
雪    币: 76
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
不对吧,我在网上查了下。__stdcall 和__cdecl都是采用自右向左的入栈方式,也就是push r , push q , push p

那[EBP+12]等于p又怎么解释呢,不是应该是[EBP+8]吗?
2010-4-30 18:00
0
雪    币: 133
活跃值: (113)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
4
我认为:
EBP+4=ret
EBP+8=参数1
EBP+C=参数2
EBP+10=参数3
......
StdCall
2010-4-30 18:29
0
雪    币: 76
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
5
嗯。我原先的预期结果也是这样的。可结果不是这样的,
EBP+0c=参数1
EBP+10=参数2
EBP+14=参数3
2010-4-30 20:48
0
雪    币: 360
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
rol
6
你调试一下,看看ebp+8是什么不就行了吗,说不准是个隐含指针呢,不看不知道
2010-4-30 20:50
0
雪    币: 76
活跃值: (25)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
7
今天我又看了会。知道为什么了。
因为汇编子过程里,开始的时候,我手动写了
PUSH EBP
MOV EBP, ESP
VC在编译时,会自动产生的。这样就相当于EBP进了两次栈。所以后面第一个参数是 [EBP+12]。我把自己添加的前面两行去掉后,就可以了。[EBP+4]是返回地址,[EBP+8]是第一个参数,,[EBP+12]是第二个参数,[EBP+16]是第三个参数。

谢谢大家的帮助!
2010-5-1 21:46
0
游客
登录 | 注册 方可回帖
返回
//