步调编译完成之后,运行之前,步调内部有地点的概念吗?
步调内部有地点。在 vs 编译调试时,假如你转到汇编上,你就可以看到编译之后的每条代码,都是有地点的,包罗函数名、变量名,在编译之后都是以地点的情势举行地点,调用一个函数,会变化为 call 一个函数的地点。再诸如 C++ 的继承多态中的虚函数表,在编译时就已经为虚函数表分配地点了,包罗表内有各种派生类的方法的地点。
而且,在编译时为各段代码分配的地点,该地点是有分段的,诸如进程地点空间中分成了代码区、未初始化、已初始化等等各种地区,这是为了方便后续加载代码计划的,也就是说编译器,也是要思量操纵体系的(编译器编译的步调是要被操纵体系加载的,以是须要照顾该步调加载到内存的标题,即进程地点空间的分段)。而在编译时给步调分配的地点,是捏造地点!只不外假如该步调还没有被加载,我们更多的称为 逻辑地点。
当进程的 PCB、进程地点空间、页表等布局都创建完成之后,该进程怎样实行第一条指令呢
当一个步调被编译完成之后,步调内部的表头就已经存储了一个 entry 步调入口地点的信息,这个入口地点也是逻辑地点(由于编译后就有这个地点了,还没加载到内存,以是不大概是物理地点)。而 CPU 为了知道下一次实行哪一条指令,在 CPU 内部维护了一个 PC 寄存器,用于存储下一条实行的指令地点。而当一个步调被加载到内存时,其入口地点就已经被加载到 CPU 内部的 PC 寄存器中了。而由于在编译后,入口地点就是捏造地点了,因此 CPU 可以直接访问这个捏造地点,然后开始实行该步调。
接着,顺着这个捏造地点到页表中寻址映射的物理地点,假云云时发现该步调还没有创建物理地点的映射(即该步调还没有被加载到内存中),那么就发生缺页停止,等步调的代码和数据加载到内存中了,每条指令天然的就有了物理地点,加上步调内部本身的捏造地点,就可以或许完成对页表的捏造地点到物理地点的映射!
顺着步调中的代码实行下去,当下一条指令遇到函数调用处,其代码会被表明为 call 一个地点,假设 call 400450,那么 CPU 读取到的指令就是地点,这个地点是代码编译完后形成的地点!因此 CPU 读取到的地点也是捏造地点!然后 CPU 再顺着该捏造地点到进程地点空间中寻址,接着通过页表映射到物理地点,再次访问物理地点。后续大概另有调用函数,CPU 照旧读取到捏造地点,然后再顺着捏造地点映射到物理地点举行访存,这不就是一个环吗! 实行该步调一套操纵下来,你应该要知道,CPU 读取到的地点,全部都是捏造地点!