说你做:
void something()
{
int* number = new int(16);
int* sixteen = number;
}
Run Code Online (Sandbox Code Playgroud)
CPU如何知道我想要分配给16的地址?
谢谢
你的示例代码没有魔力.拿这个片段,例如:
int x = 5;
int y = x;
Run Code Online (Sandbox Code Playgroud)
您与指针的代码是完全一样的-电脑并不需要知道任何神奇的信息,它只是复制无论在number成sixteen.
至于你的评论如下:
但是它如何知道x或y在内存中的位置.如果我要求将x复制到y中,它是如何知道其中任何一个的.
实际上,在目前的大多数机器上,可能它们都不在记忆中,它们会在寄存器中.但是如果它们在内存中,那么是的,编译器将发出代码,根据需要跟踪所有这些地址.在这种情况下,它们将位于堆栈中,因此机器代码将访问堆栈指针寄存器,并使用一些编译器决定的偏移量来解除引用它,这些偏移量指的是每个特定变量的存储.
这是一个例子.这个简单的功能:
int f(void)
{
int x = 5;
int y = x;
return y;
}
Run Code Online (Sandbox Code Playgroud)
使用clang编译并且没有优化时,在我的机器上给出以下输出:
_f:
pushq %rbp ; save caller's base pointer
movq %rsp,%rbp ; copy stack pointer into base pointer
movl $5,0xfc(%rbp) ; store constant 5 to stack at rbp-4
movl 0xfc(%rbp),%eax ; copy value at rbp-4 to register eax
movl %eax,0xf8(%rbp) ; copy value from eax to stack at rbp-8
movl 0xf8(%rbp),%eax ; copy value off stack to return value register eax
popq %rbp ; restore caller's base pointer
ret ; return from function
Run Code Online (Sandbox Code Playgroud)
我添加了一些注释来解释生成的代码的每一行的作用.重要的事情是堆栈上有两个变量 - 一个在0xf8(%rbp)(或rbp-8更清晰),一个在0xfc(%rbp)(或rbp-4).基本算法就像原来的代码显示-恒5被保存到x的rbp-4,则该值将被复制到y的rbp-8.
"但是,在没有堆栈来的?" 你可能会问.不过,问题的答案是依赖于操作系统和编译器.它是main在调用程序函数之前设置的,与操作系统所需的其他运行时设置同时进行.