“确定被调用的宿主有关问题”各种语言版大征集

“确定被调用的宿主问题”各种语言版大征集!
C语言版:需要尽量简单地设置编译链接选项。VC6
http://topic.csdn.net/u/20120530/05/A9E5E49E-940A-44AE-96A5-A0E7DB986C10.html
C/C++ code
#include <stdio.h>
void whocallme();
void fun1() {
    whocallme();
}
void fun2() {
    whocallme();
}
void fun3() {
    fun1();
}
void whocallme() {
    int *_esp,i;
    __asm {
        mov eax,esp
        mov _esp,eax
    }
    printf("\nfun1,fun2,fun3,_esp=%08x,%08x,%08x,%08x\n",(int)fun1,(int)fun2,(int)fun3,(int)_esp);
    for (i=0;i<100;i++) if (_esp[i]==(int)_esp) break;
    if (i<100) {
        printf("ret addr=%08x\n",_esp[i+2]);
        if ((int)fun1<=_esp[i+2] && _esp[i+2]<(int)fun2) printf("fun1 callme\n");
        if ((int)fun2<=_esp[i+2] && _esp[i+2]<(int)fun3) printf("fun2 callme\n");
    }
}
void main() {
    fun2();
    fun1();
}
//C:\tmp\tmp\Debug>tmp
//
//fun1,fun2,fun3,_esp=00401000,00401020,00401040,0012fe84
//ret addr=0040102e
//fun2 callme
//
//fun1,fun2,fun3,_esp=00401000,00401020,00401040,0012fe84
//ret addr=0040100e
//fun1 callme
//
//C:\tmp\tmp\Debug>cd ..\release
//
//C:\tmp\tmp\Release>tmp
//
//fun1,fun2,fun3,_esp=00401000,0040100a,00401014,0012ff5c
//ret addr=00401012
//fun2 callme
//
//fun1,fun2,fun3,_esp=00401000,0040100a,00401014,0012ff5c
//ret addr=00401008
//fun1 callme
//



欢迎大家在下面踊跃给出其它语言版:

------解决方案--------------------
赵老师发帖,顶起!
------解决方案--------------------
探讨

赵老师发帖,顶起!

------解决方案--------------------
赵老师发帖,顶起!
------解决方案--------------------
赵大侠一向很牛X
------解决方案--------------------
不懂,支持赵老师一个
------解决方案--------------------
看到LZ的帖子,我只能说我被雷到了,我每天大部分时间会接触不同平台的汇编语言(至少两种,算法,没办法,不是我想),但我不会想到居然用汇编 ---- 不同平台光改汇编就改死你;这么简单的问题为什么搞得如此的复杂,怪不得外行人都说IT很复杂呢;假设这个程序不是你写的,出问题的函数是客户的(你无法加whocallme)?假设现在不是VC6++呢,用户偏偏喜好GCC呢?。。。
这个帖子已经回复:http://topic.csdn.net/u/20120530/05/a9e5e49e-940a-44ae-96a5-a0e7db986c10.html?seed=1214750586&r=78880293#r_78880293
实际可适用语言不止c/c++;
------解决方案--------------------
看不懂啊,还得继续努力!