gpt4 book ai didi

c - 使用 C 中的函数指针重新启动计算机

转载 作者:太空宇宙 更新时间:2023-11-04 05:26:11 25 4
gpt4 key购买 nike

当我遇到一个在执行时重新启动计算机的程序时,我正在学习 C 中的函数指针。

void (*f) (void);
f=(void (*)(void) MK_FP(0xFFFF,0x0000);
f();

(void (*)(void)) 部分不在提供的原始文本中,我必须添加此内容才能编译代码。这是如何工作的?

非常感谢。

最佳答案

关于从数字文字手动构造函数指针并调用它们的程序,C 标准仅表示行为未定义。这意味着您不能期望该程序在不同计算机之间,甚至在同一台计算机上运行时表现相同。

关于这个特定的程序,我们可以对它的意图以及在什么情况下它实际会这样做做出有根据的猜测:

最初的 IBM PC 的原始操作系统,通常称为 MS-DOS,在开机时开始在分段地址 FFFF:0000 处执行代码。 (有些消息来源说 F000:FFF0 —— 由于太乏味的原因无法进入这里,那是相同的物理地址,但表达方式不同,并且可能表现不同,具体取决于关于那个位置的代码。)因为这个操作系统非常简单,所以在机器启动并运行后跳转到那个位置将执行近似于热重启。

假设您的 MK_FP 宏从段和偏移值构造一个分段函数指针,那么,当您的程序在运行 MS-DOS 的 IBM PC 上执行时 ,它跳转到 FFFF:0000 并执行近似于热重启。

在更现代的操作系统(包括 IBM PC 后代的所有当前操作系统)上,此程序保证不会重新启动计算机,因为非特权用户模式程序不是允许 重新启动计算机。此外,MK_FP() 操作本身在现代 32 位或 64 位用户模式程序中没有意义,因为它们在平面地址空间中运行。代码可能会编译,但它几乎肯定会调用一个没有内存映射到它的地址,所以我预计程序会崩溃。但是操作系统的其余部分将继续运行,就像什么也没发生一样。如果您在 DOS 模拟器中运行该程序,它可能会重新启动模拟器,但同样,操作系统的其余部分将继续运行。

有可能编写一个重新启动现代操作系统的程序——事实上,您的计算机上已经至少有一个这样的程序,否则您将无法重新启动它物理电源开关! -- 但它必须很好地询问内核,使用特殊的系统调用(Unix 系列:reboot(2) ;Windows:ExitWindowsEx)并且它必须以特殊权限运行,否则调用将失败。

就是说,跳转到 FFFF:0000 加上一堆辅助的小鸡挥手 是当前版本的 Linux 可能使用的低级操作之一在基于 x86 的机器上触发重启。只有在其他几件事失败时才会尝试,但它就在那里。参见 http://lxr.free-electrons.com/source/arch/x86/kernel/reboot.c#L484有关整个程序的概述,以及 http://lxr.free-electrons.com/source/arch/x86/realmode/rm/reboot.S对于在回落到“真实”(16 位分段)模式后实际执行跳转至 FFFF:0000 的代码。

关于c - 使用 C 中的函数指针重新启动计算机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26387105/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com