VS里怎么能从"转到定义" 返回

VS里怎么能从"转到定义" 返回,第1张

对于函数而言,在另一个cpp文件中定义的函数,在当前cpp中调用之前需要做一下声明。
转到声明:会跳到声明语句。
转到定义:会跳到另一个cpp中该函数的位置。
对于宏和变量而言,这两个作用是一样的。

教科书中一般说,在C/C++中,函数通过eax寄存器返回结果。如果结果不大于4字节,则eax就是它的值;如果大于4字节,则返回存放它的内存地址。
请思考如下的问题:
如果函数返回的结果大于4字节,那么它被存放到哪里了?
一般情况下,局部变量通过add esp -4n或者push ecx从堆栈获得存储空间。如果结果也像局部变量这般,那么返回以后,它有可能被后续 *** 作覆盖掉。所以应该把在调用函数前就为它分配空间。
这段空间分配在哪里?函数如何使用它?这是进一步引申出来的问题。
下面我们就做几个实验来观察一下。(如果想直接看结果,可以跳到本文最后的总结。)
先介绍实验环境。C源程序经过Microsoft Visual C++ 60自带的命令行工具clexe(版本12081680)编译,不加任何参数。
先看返回值为4字节的情况。源代码如下:
typedef struct stSize4{
char a;
char b;
short c;
} stSize4;
stSize4 stFunc(short num)
{
stSize4 temp = {'t','h',num};
return temp;
}
void main()
{
stSize4 target;
target = stFunc(1745);
}
编译后,反汇编结果如下:
00401000 push ebp ;stFunc()
00401001 mov ebp, esp
00401003 push ecx ;4字节局部变量temp
00401004 mov byte ptr ss:[ebp-4], 74
00401008 mov byte ptr ss:[ebp-3], 68
0040100C mov ax, word ptr ss:[ebp+8] ;取出参数
00401010 mov word ptr ss:[ebp-2], ax
00401014 mov eax, dword ptr ss:[ebp-4] ;把值直接赋给eax
00401017 mov esp, ebp
00401019 pop ebp
0040101A ret
0040101B push ebp ;main()
0040101C mov ebp, esp
0040101E push ecx ;4字节局部变量target
0040101F push 6D1 ;参数入栈
00401024 call 00401000
00401029 add esp, 4 ;堆栈平衡
0040102C mov dword ptr ss:[ebp-4], eax ;把eax的值保存
0040102F mov esp, ebp
00401031 pop ebp
00401032 ret
正如教科书所言,结果被直接存储在eax中返回了。
接下来我们写一个返回值为8字节的程序。
typedef struct stSize8{
short a;
short b;
short c;
short d;
} stSize8;
stSize8 stFunc(short num)
{
stSize8 temp = {100,200,300,num};
return temp;
}
void main()
{
stSize8 target;
target = stFunc(1745);
}
反汇编后,出现了一些不同的情况:
00401000 push ebp ;stFunc()
00401001 mov ebp, esp
00401003 sub esp, 8 ;8字节局部变量temp
00401006 mov word ptr ss:[ebp-8], 64
0040100C mov word ptr ss:[ebp-6], 0C8
00401012 mov word ptr ss:[ebp-4], 12C
00401018 mov ax, word ptr ss:[ebp+8] ;取出参数
0040101C mov word ptr ss:[ebp-2], ax
00401020 mov eax, dword ptr ss:[ebp-8] ;低位的值存到eax
00401023 mov edx, dword ptr ss:[ebp-4] ;高位的值存到edx
00401026 mov esp, ebp
00401028 pop ebp
00401029 ret
0040102A push ebp ;main()
0040102B mov ebp, esp
0040102D sub esp, 8 ;8字节局部变量target
00401030 push 6D1 ;参数入栈
00401035 call 00401000
0040103A add esp, 4 ;堆栈平衡
0040103D mov dword ptr ss:[ebp-8], eax ;把eax的值存到局部变量
00401040 mov dword ptr ss:[ebp-4], edx ;把edx的值存到局部变量
00401043 mov esp, ebp
00401045 pop ebp
00401046 ret
此时并不是通常说的eax返回一个地址,而是使用eax存储8位结果的低4位值,同时使用ebx存储8位结果的高四位值,一并返回给调用者。
再来写一个3字节的:
typedef struct stSize3{
char a;
char b;
char c;
} stSi >DebugRemoveAllBreakpoints Ctrl+Shift+F9 Removes all breakpoints
DebugStepOver F10 Steps over the next statement
DebugStepInto F11 Steps into the next statement
DebugGo F5 Starts or continues the program (Ctrl + F5 编译连接运行)
DebugToggleBreakpoint F9 Inserts or removes a breakpoint
DebugStepOut Shift+F11 Steps out of the current function
DebugStopDebugging Shift+F5 Stops debugging the program

应该是VC环境错了:当前代码是控制台程序,工程环境却是win32 应用程序的,win32应用程序的入口是WinMain()不是main()
修改:
project-->settings先择link选项卡,在最下面的project options 把 /subsystem:windows 改成 /subsystem:console

跟我一样,捉摸半天,也百度了半天。说的都没用。然后我在没一个小窗体空白处点击右键,会出现一个组合的选项,选中就可以了。注意每个窗体都要右击。你右击某一个窗口选择组合时,你会发现其他的小窗口都被遮住了,莫慌,你点击上面的Window选项卡,在倒数第一行(窗口)上面有1输出,2你起的文件名cp。
这个1和2就是你的哪些小窗口,点击其中一个没组合的窗口,它就会显示出来,你再点右击组合。重复这样的 *** 作就可以了


欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/yw/13389485.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-07-26
下一篇 2023-07-26

发表评论

登录后才能评论

评论列表(0条)

保存