Process PC寄存器是否可以指向与文本段不同的内存区域?

Process PC寄存器是否可以指向与文本段不同的内存区域?,process,operating-system,cpu-registers,Process,Operating System,Cpu Registers,关于PC注册,我有两个问题: 如果一个CPU的PC寄存器指向一个不在进程文本段中的内存单元,那么它是否会崩溃?如果是这样的话,是进程刚刚终止还是机器死机 当cpu执行一个进程时,它通过递增PC来不断迭代指令。让我们假设PC指向最后一条指令。CPU如何知道进程已完成,从而不会增加PC 对于第二个问题,我认为可以通过查看堆栈中的帧数来完成。如果我们在最后一帧调用return,那么该过程通常已经完成。但实际上是这样吗?在案例1中,当程序计数器指向无效地址时,处理器会引发异常,因为MMU将指示故障。

关于PC注册,我有两个问题:

  • 如果一个CPU的PC寄存器指向一个不在进程文本段中的内存单元,那么它是否会崩溃?如果是这样的话,是进程刚刚终止还是机器死机

  • 当cpu执行一个进程时,它通过递增PC来不断迭代指令。让我们假设PC指向最后一条指令。CPU如何知道进程已完成,从而不会增加PC


  • 对于第二个问题,我认为可以通过查看堆栈中的帧数来完成。如果我们在最后一帧调用return,那么该过程通常已经完成。但实际上是这样吗?

    在案例1中,当程序计数器指向无效地址时,处理器会引发异常,因为MMU将指示故障。操作系统通常会终止该进程,例如使用SIGSEGV。通过执行
    ((void(*)(void))(0xDEADBEEF)),您可以在C中轻松地尝试这一点(替换为任何无效地址)。如果这样一个简单的内存故障会使机器崩溃,那将是一个巨大的安全问题

    如果这种无效访问发生在内核空间内,则取决于内核是否已将该位置配置为在MMU中不可访问。如果是,CPU将再次导致异常,内核可对此做出响应,例如打印错误消息。如果没有,行为很大程度上取决于CPU和所涉及的地址;可能有一些硬故障异常导致系统崩溃,或者根本没有发生任何事情


    案例2永远不会发生。当C中的
    main()
    函数返回时,C运行时库执行系统调用,之后操作系统将终止进程。如果使用汇编语言编写代码,则必须在程序应该退出时手动调用该系统调用。请注意,在
    main()
    函数之后,内存中可能还有其他函数,当然不应在
    main()
    返回后执行这些函数。程序文本段中的最后一条指令需要是对某条有效指令的某种跳转/返回/调用;如果它是一条“普通”指令,如
    add
    ,CPU随后将尝试执行一个无效的内存位置,在这种情况下1适用(程序终止/崩溃)。当然,在C程序中,所有代码都是按函数组织的,每个函数都以返回/跳转指令结束,因此C程序文本段中的最后一条指令实际上是返回/跳转指令。

    谢谢您的回答!对于案例2的答案,如果汇编程序不调用exit怎么办?那么程序将执行未定义的操作;当CPU试图在文本段之外执行一个内存位置时,可能会崩溃,该内存位置尚未被操作系统配置为现有的和可执行的,这会导致异常。对于案例1,它是否与段有关,并且每个段都有其访问权限?如果是这样,我假设cpu将其每个寄存器映射到它们可以指向的段(PC到文本,SP到堆栈,…),但我不确定该映射存储在哪里?它与MMU页面有关。操作系统为可执行文件中的程序段分配MMU页面,并根据需要将MMU页面配置为可读/可执行/可写。要启动程序,操作系统将电脑设置为程序入口点(通常称为
    \u start
    ,在文件头中定义)。然后,程序有责任不将其设置为无效值(即跳转到无效地址)。。。不检查寄存器的内容。仅检查内存访问。由于每一条指令都会自动访问PC,因此将PC指向无效地址将导致立即崩溃。让SP指向无效地址只会在访问包含的地址时崩溃。内存单元不能包含无效内容,但OS+MMU可以禁止访问某些位置,因此如果您试图访问这些位置,程序将终止;实际访问从未发生,就像以前发生的异常一样。