原文链接:http://blog.csdn.net/goodname008/archive/2004/07/24/50662.aspx
原文作者:卢培培(goodname008)
|
关键字
|
清理堆栈
|
参数入栈顺序
|
函数名称修饰(C)
|
|
__cdecl
|
调用函数
|
右 à左
|
_函数名
|
|
__stdcall
|
被调用函数
|
右 à左
|
_函数名@数字
|
|
__fastcall
|
被调用函数
|
右 à左
|
@函数名@数字
|
|
thiscall(非关键字)
|
被调用函数
|
右 à左
|
/
|
|
int __cdecl Sumcdecl(int a, int b, int c)
{
int i = 1000;
short j = 2000;
int k = 3000;
int rEBP = 0;
int value = 0;
// ...
return (a + b + c);
}
调用:Sumcdecl(10, 20, 30);
|
|
0
|
value
|
|
0
|
rEBP
|
|
3000
|
k
|
|
2000
|
j
|
|
1000
|
i
|
|
|
<---------EBP
|
|
|
|
|
10
|
a
|
|
20
|
b
|
|
30
|
c
|
|
|
|
|
[未使用]
|
ECX
|
|
[未使用]
|
EDX
|
|
#include "iostream.h"
#include "stdio.h"
extern "C" __declspec(dllexport) int __cdecl Sumcdecl(int a, int b, int c)
{
// 声明局部变量
int i = 1000;
short j = 2000;
int k = 3000;
int rEBP = 0;
int value = 0;
// 显示局部变量的地址
cout << "局部变量的地址:" << endl;
cout << &value << " <-----------value" << endl;
cout << &rEBP << " <-----------rEBP" << endl;
cout << &k << " <-----------k" << endl;
cout << &j << " <-----------j" << endl;
cout << &i << " <-----------i" << endl;
// 显示寄存器的值
cout << "寄存器:" << endl;
__asm mov rEBP, ebp;
printf("0x%08X <-----------EBP\n", rEBP);
// 显示函数参数的地址
cout << "函数参数的地址:" << endl;
cout << &a << " <-----------a" << endl;
cout << &b << " <-----------b" << endl;
cout << &c << " <-----------c" << endl;
// 通过 EBP 寄存器获得堆栈中的数据并显示
cout << "通过EBP获取堆栈中的数据:" << endl;
__asm mov eax, [ebp - 4];
__asm mov value, eax;
cout << "i: " << value << endl;
__asm mov eax, [ebp - 8];
__asm mov value, eax;
cout << "j: " << (short)value << endl;
__asm mov eax, [ebp - 12];
__asm mov value, eax;
cout << "k: " << value << endl;
__asm mov eax, [ebp + 8];
__asm mov value, eax;
cout << "a: " << value << endl;
__asm mov eax, [ebp + 12];
__asm mov value, eax;
cout << "b: " << value << endl;
__asm mov eax, [ebp + 16];
__asm mov value, eax;
cout << "c: " << value << endl;
// 返回
return (a + b + c);
}
// 主函数
int main(int argc, char* argv[])
{
Sumcdecl(10, 20, 30);
return 0;
}
|
|
局部变量的地址:
0x0012FF0C <-----------value
0x0012FF10 <-----------rEBP
0x0012FF14 <-----------k
0x0012FF18 <-----------j
0x0012FF1C <-----------i
寄存器:
0x0012FF20 <-----------EBP
函数参数的地址:
0x0012FF28 <-----------a
0x0012FF2C <-----------b
0x0012FF30 <-----------c
通过EBP获取堆栈中的数据:
i: 1000
j: 2000
k: 3000
a: 10
b: 20
c: 30
|
|
File Type: LIBRARY
Exports
ordinal name
_Sumcdecl
Summary
C9 .debug$S
14 .idata$2
14 .idata$3
4 .idata$4
4 .idata$5
E .idata$6
|
|
int __stdcall Sumstdcall(int a, int b, int c)
{
int i = 1000;
short j = 2000;
int k = 3000;
int rEBP = 0;
int value = 0;
// ...
return (a + b + c);
}
调用:Sumstdcall(10, 20, 30);
|
|
0
|
value
|
|
0
|
rEBP
|
|
3000
|
k
|
|
2000
|
j
|
|
1000
|
i
|
|
|
<---------EBP
|
|
|
|
|
10
|
a
|
|
20
|
b
|
|
30
|
c
|
|
|
|
|
[未使用]
|
ECX
|
|
[未使用]
|
EDX
|
|
#include "iostream.h"
#include "stdio.h"
extern "C" __declspec(dllexport) int __stdcall Sumstdcall(int a, int b, int c)
{
// 声明局部变量
int i = 1000;
short j = 2000;
int k = 3000;
int rEBP = 0;
int value = 0;
// 显示局部变量的地址
cout << "局部变量的地址:" << endl;
cout << &value << " <-----------value" << endl;
cout << &rEBP << " <-----------rEBP" << endl;
cout << &k << " <-----------k" << endl;
cout << &j << " <-----------j" << endl;
cout << &i << " <-----------i" << endl;
// 显示寄存器的值
cout << "寄存器:" << endl;
__asm mov rEBP, ebp;
printf("0x%08X <-----------EBP\n", rEBP);
// 显示函数参数的地址
cout << "函数参数的地址:" << endl;
cout << &a << " <-----------a" << endl;
cout << &b << " <-----------b" << endl;
cout << &c << " <-----------c" << endl;
// 通过 EBP 寄存器获得堆栈中的数据并显示
cout << "通过EBP获取堆栈中的数据:" << endl;
__asm mov eax, [ebp - 4];
__asm mov value, eax;
cout << "i: " << value << endl;
__asm mov eax, [ebp - 8];
__asm mov value, eax;
cout << "j: " << (short)value << endl;
__asm mov eax, [ebp - 12];
__asm mov value, eax;
cout << "k: " << value << endl;
__asm mov eax, [ebp + 8];
__asm mov value, eax;
cout << "a: " << value << endl;
__asm mov eax, [ebp + 12];
__asm mov value, eax;
cout << "b: " << value << endl;
__asm mov eax, [ebp + 16];
__asm mov value, eax;
cout << "c: " << value << endl;
// 返回
return (a + b + c);
}
// 主函数
int main(int argc, char* argv[])
{
Sumstdcall(10, 20, 30);
return 0;
}
|
|
局部变量的地址:
0x0012FF0C <-----------value
0x0012FF10 <-----------rEBP
0x0012FF14 <-----------k
0x0012FF18 <-----------j
0x0012FF1C <-----------i
寄存器:
0x0012FF20 <-----------EBP
函数参数的地址:
0x0012FF28 <-----------a
0x0012FF2C <-----------b
0x0012FF30 <-----------c
通过EBP获取堆栈中的数据:
i: 1000
j: 2000
k: 3000
a: 10
b: 20
c: 30
|
|
File Type: LIBRARY
Exports
ordinal name
_Sumstdcall@12
Summary
C9 .debug$S
14 .idata$2
14 .idata$3
4 .idata$4
4 .idata$5
E .idata$6
|
|
int __fastcall Sumfastcall(int a, double x, int b, int c)
{
int i = 1000;
short j = 2000;
int k = 3000;
int rEBP = 0;
int rECX = 0;
int rEDX = 0;
int value = 0;
// ...
return (a + b + c);
}
调用:Sumfastcall(10, 8.8, 20, 30);
|
|
0
|
value
|
|
0
|
rEDX
|
|
0
|
rECX
|
|
0
|
rEBP
|
|
3000
|
k
|
|
2000
|
j
|
|
1000
|
i
|
|
20
|
b
|
|
10
|
a
|
|
|
<---------EBP
|
|
|
|
|
8.8
|
x(8个字节)
|
|
30
|
c
|
|
|
|
|
10
|
ECX
|
|
20
|
EDX
|
|
#include "iostream.h"
#include "stdio.h"
extern "C" __declspec(dllexport) int __fastcall Sumfastcall(int a, double x, int b, int c)
{
// 声明局部变量
int i = 1000;
short j = 2000;
int k = 3000;
int rEBP = 0;
int rECX = 0;
int rEDX = 0;
int value = 0;
// 显示 ECX 和 EDX 寄存器的值
__asm mov rECX, ecx;
__asm mov rEDX, edx;
cout << "ECX 和 EDX 寄存器的值:" << endl;
cout << "ECX: " << rECX << endl;
cout << "EDX: " << rEDX << endl;
// 显示局部变量的地址
cout << "局部变量的地址:" << endl;
cout << &value << " <-----------value" << endl;
cout << &rEDX << " <-----------rEDX" << endl;
cout << &rECX << " <-----------rECX" << endl;
cout << &rEBP << " <-----------rEBP" << endl;
cout << &k << " <-----------k" << endl;
cout << &j << " <-----------j" << endl;
cout << &i << " <-----------i" << endl;
// 显示存入寄存器的参数的地址, 变量虽然存入了寄存器, 但也在堆栈中
cout << "显示存入寄存器的参数的地址:" << endl;
cout << &b << " <-----------b" << endl;
cout << &a << " <-----------a" << endl;
// 显示寄存器的值
cout << "寄存器:" << endl;
__asm mov rEBP, ebp;
printf("0x%08X <-----------EBP\n", rEBP);
// 显示函数参数的地址
cout << "函数参数的地址:" << endl;
cout << &x << " <-----------x" << endl;
cout << &c << " <-----------c" << endl;
// 通过 EBP 寄存器获得堆栈中的数据并显示
cout << "通过EBP获取堆栈中的数据:" << endl;
__asm mov eax, [ebp - 12];
__asm mov value, eax;
cout << "i: " << value << endl;
__asm mov eax, [ebp - 16];
__asm mov value, eax;
cout << "j: " << (short)value << endl;
__asm mov eax, [ebp - 20];
__asm mov value, eax;
cout << "k: " << value << endl;
__asm mov eax, [ebp - 4];
__asm mov value, eax;
cout << "a: " << value << endl;
__asm mov eax, [ebp - 8];
__asm mov value, eax;
cout << "b: " << value << endl;
__asm mov eax, [ebp + 16];
__asm mov value, eax;
cout << "c: " << value << endl;
// 返回
return (a + b + c);
}
// 主函数
int main(int argc, char* argv[])
{
Sumfastcall(10, 8.8, 20, 30);
return 0;
}
|
|
ECX 和 EDX 寄存器的值:
ECX: 10
EDX: 20
局部变量的地址:
0x0012FEFC <-----------value
0x0012FF00 <-----------rEDX
0x0012FF04 <-----------rECX
0x0012FF08 <-----------rEBP
0x0012FF0C <-----------k
0x0012FF10 <-----------j
0x0012FF14 <-----------i
显示存入寄存器的参数的地址:
0x0012FF18 <-----------b
0x0012FF1C <-----------a
寄存器:
0x0012FF20 <-----------EBP
函数参数的地址:
0x0012FF28 <-----------x
0x0012FF30 <-----------c
通过EBP获取堆栈中的数据:
i: 1000
j: 2000
k: 3000
a: 10
b: 20
c: 30
|
|
File Type: LIBRARY
Exports
ordinal name
@Sumfastcall@20
Summary
C9 .debug$S
14 .idata$2
14 .idata$3
4 .idata$4
4 .idata$5
E .idata$6
|
|
class Test
{
public:
int Sumthiscall(int a, int b, int c)
{
int i = 1000;
short j = 2000;
int k = 3000;
int rEBP = 0;
int value = 0;
// ...
return (a + b + c);
}
};
调用:
Test test;
test.Sumthiscall(10, 20, 30);
|
|
0
|
value
|
|
0
|
rEBP
|
|
3000
|
k
|
|
2000
|
j
|
|
1000
|
i
|
|
对象地址
|
this
|
|
|
<---------EBP
|
|
|
|
|
10
|
a
|
|
20
|
b
|
|
30
|
c
|
|
|
|
|
对象地址
|
ECX
|
|
[未使用]
|
EDX
|
|
#include "iostream.h"
#include "stdio.h"
class Test
{
public:
int Sumthiscall(int a, int b, int c)
{
// 声明局部变量
int i = 1000;
short j = 2000;
int k = 3000;
int rEBP = 0;
int value = 0;
// 通过 ECX 寄存器获得 this 指针
__asm mov value, ecx;
printf("通过ECX 寄存器获得 this 指针: 0x%08X\n", value);
// 直接输出 this 所指对象的地址
printf("直接输出 this 所指对象的地址: 0x%08X\n", this);
// 显示局部变量的地址
cout << "局部变量的地址:" << endl;
cout << &value << " <-----------value" << endl;
cout << &rEBP << " <-----------rEBP" << endl;
cout << &k << " <-----------k" << endl;
cout << &j << " <-----------j" << endl;
cout << &i << " <-----------i" << endl;
// 显示寄存器的值
cout << "寄存器:" << endl;
__asm mov rEBP, ebp;
printf("0x%08X <-----------EBP\n", rEBP);
// 显示函数参数的地址
cout << "函数参数的地址:" << endl;
cout << &a << " <-----------a" << endl;
cout << &b << " <-----------b" << endl;
cout << &c << " <-----------c" << endl;
// 通过 EBP 寄存器获得堆栈中的数据并显示
cout << "通过EBP获取堆栈中的数据:" << endl;
__asm mov eax, [ebp - 4];
__asm mov value, eax;
printf("this: 0x%08X\n", value);
__asm mov eax, [ebp - 8];
__asm mov value, eax;
cout << "i: " << value << endl;
__asm mov eax, [ebp - 12];
__asm mov value, eax;
cout << "j: " << (short)value << endl;
__asm mov eax, [ebp - 16];
__asm mov value, eax;
cout << "k: " << value << endl;
__asm mov eax, [ebp + 8];
__asm mov value, eax;
cout << "a: " << value << endl;
__asm mov eax, [ebp + 12];
__asm mov value, eax;
cout << "b: " << value << endl;
__asm mov eax, [ebp + 16];
__asm mov value, eax;
cout << "c: " << value << endl;
// 返回
return (a + b + c);
}
};
// 主函数
int main(int argc, char* argv[])
{
Test test;
test.Sumthiscall(10, 20, 30);
return 0;
}
|
|
通过ECX 寄存器获得 this 指针: 0x0012FF7C
直接输出 this 所指对象的地址: 0x0012FF7C
局部变量的地址:
0x0012FF04 <-----------value
0x0012FF08 <-----------rEBP
0x0012FF0C <-----------k
0x0012FF10 <-----------j
0x0012FF14 <-----------i
寄存器:
0x0012FF1C <-----------EBP
函数参数的地址:
0x0012FF24 <-----------a
0x0012FF28 <-----------b
0x0012FF2C <-----------c
通过EBP获取堆栈中的数据:
this: 0x0012FF7C
i: 1000
j: 2000
k: 3000
a: 10
b: 20
c: 30
|
|
?Sumcdecl@@YAHHHH@Z (int __cdecl Sumcdecl(int,int,int))
?Sumfastcall@@YIHHNHH@Z (int __fastcall Sumfastcall(int,double,int,int))
?Sumstdcall@@YGHHHH@Z (int __stdcall Sumstdcall(int,int,int))
|
|
代 号
|
类 型
|
|
X
|
void
|
|
D
|
char
|
|
E
|
unsigned char
|
|
F
|
short
|
|
H
|
int
|
|
I
|
unsigned int
|
|
J
|
long
|
|
K
|
unsigned long
|
|
M
|
float
|
|
N
|
double
|
|
_N
|
bool
|
|
O
|
long double
|
|
PA
|
指针前缀
|
|
AA
|
引用前缀
|
|
V类名@@
|
类
|
发表于 @ 2006年09月21日 13:56:00 | 评论( loading... ) | 举报| 收藏