我想知道,处理器如何知道何时停止执行程序。或者更确切地说,何时停止" fetch,解码执行"周期。
我想到了不同的方法,但不确定哪一个是正确的,或者它们都是错的
1-也许最后由汇编程序自动添加一条特殊指令让处理器知道这是结束
2-当它到达无效的内存时(但它如何识别)
3-它循环并重新运行程序,但它又如何识别何时循环或者汇编器自动添加它。
4-或者它根本不会停止,它会一直运行。 (但这种能力效率低下吗?
请指教。
如果答案因处理器而异,我们以MIPS和x86为例。
感谢。
答案 0 :(得分:2)
这取决于操作系统和处理器。
对于具有暂停指令(如X86)的处理器,当所有进程和线程都处于等待状态(无事可做)时,操作系统可能会执行暂停指令,该指令将暂停cpu并等待中断。如果下一个中断没有导致任何线程的状态切换为可运行,那么操作系统将返回暂停指令。
在没有暂停指令的cpu上,当所有线程都在等待时,操作系统进入一个只分支到自身的空闲循环。
回到最初的问题,运行程序的基本顺序是为程序初始分配内存空间,加载程序,然后调用程序。程序最终应该从回调函数返回到操作系统,操作系统将释放分配用于运行程序的内存。操作系统还可以在初始分配阶段创建虚拟地址空间。
wiki loader,wiki program execution。在MSDOS的情况下,程序使用INT软件序列返回MSDOS,例如设置AH = 04Ch然后执行INT 21H。对于其他操作系统,加载程序会调用程序,该程序在完成后返回。
答案 1 :(得分:1)
与之前的回复有一些相似之处,我将更详细地描述。应区分两个主要的上下文:1)直接在运行的硬件上具有管理员权限的代码(包括操作系统)和2)应用程序代码。
对于第二种情况 - 应用程序代码 - 应用程序应执行通常名为“exit”的系统调用,该系统调用通知管理程序(内核)应用程序已完成。这个电话的细节有所不同;例如如rcgldr所描述的MS-DOS AH = 4Ch / int21h就是这样的“退出”;在现代Linux中它是exit_group
系统调用;等等。当只看到main()时,你可能会错过main()由系统特定的应用程序包装器调用的事实,它执行exit()调用。如果应用程序没有显式退出,它将执行直到发生致命错误。获得此exit()请求后,supervisor将破坏该进程并切换到另一个进程。
对于主管本身,如果它停止执行,这是非常特定于平台的。对于x86,最初关闭时没有断电的主要方法是围绕HLT
指令的循环(因为后者可以在中断时自发继续)。使用相同的HLT直至约。 Pentium4和Athlon停止处理器,直到没有工作时中断;由于这些处理器需要额外的措施来阻止芯片组级活动,因此停止方法变得更加复杂。现代x86平台描述了如何根据ACPI内部语言的描述进行临时系统停止,其中包括多个系统端口编程。所有真实体系结构都存在类似的停止直到外部事件发生的指令。可以有多个级别的停止;例如一些嵌入式产品具有“轻微停止”功能,只会减慢处理器速度,“主停止”会使处理器完全停止,但需要数十微秒才能使时钟PLL稳定下来。无论如何,在这样的停止之后,主管试图继续正常工作,直到重启/断电/等。正在接触。
多处理器(多核)配置各有特色,因此最初只启动一个处理器的一个核心。然后,处理器间中断(IPI)或类似物用于启动或停止另一个核心和处理器。停止OS工作通常包括停止除最后一个之外的所有处理器和核心。
答案 2 :(得分:1)
要以8086或MIPS结尾,可以使用系统调用
在8086中:
hlt
或int 20h
在MIPS中:
hlt的代码是10,您需要将其放在$ v0或$ 2中(相同寄存器)
li $v0, 10
然后呼叫系统
syscall