面试题答案
一键面试1. 逻辑地址生成和变化
在C++中,函数调用时逻辑地址的生成与程序的编译和链接过程紧密相关。编译时,编译器会为每个函数分配一个相对地址,这个相对地址是基于程序的起始地址而言的。链接阶段,链接器会将各个目标文件中的相对地址调整为最终的逻辑地址。
当函数调用发生时,程序计数器(PC)会更新为被调用函数的逻辑地址。这个过程会使得程序流程跳转到被调用函数的起始位置开始执行。
2. 栈帧与逻辑地址的关系
- 栈帧的概念:栈帧是函数调用过程中在栈上为该函数分配的一块内存区域,用于存储函数的局部变量、参数、返回地址等信息。
- 关系阐述:每个栈帧都有其特定的逻辑地址范围。当一个函数被调用时,会在栈上创建一个新的栈帧,栈指针(通常是ESP寄存器)会移动来为新栈帧分配空间。被调用函数的参数从右向左依次压入栈中,然后返回地址被压入栈,接着为函数的局部变量分配空间。栈帧的起始地址和结束地址共同确定了该函数在栈上的逻辑地址范围。函数执行完毕后,栈帧被销毁,栈指针恢复到调用前的位置。
3. 举例说明
#include <iostream>
void func(int a, int b) {
int c = a + b;
std::cout << "Result: " << c << std::endl;
}
int main() {
int x = 3;
int y = 5;
func(x, y);
return 0;
}
在上述代码中,main
函数调用func
函数。
- 参数传递:
x
和y
的值(即3
和5
)会从右向左压入栈,为func
函数的参数a
和b
分配栈空间。 - 返回地址:
main
函数中调用func
后的下一条指令的地址(即return 0;
的地址)会被压入栈,作为返回地址。 - 局部变量:在
func
函数栈帧内,为局部变量c
分配空间。func
函数执行完毕后,其栈帧被销毁,程序回到main
函数中func
调用后的下一条指令继续执行。整个过程中,栈帧在栈上的逻辑地址范围变化清晰展示了函数调用过程中逻辑地址与栈帧的紧密联系。