【问题标题】:System calls on WindowsWindows 上的系统调用
【发布时间】:2011-02-15 02:10:23
【问题描述】:

我只是想问一下,我知道 Linux 中的标准系统调用是通过指向中断向量表的 int 指令完成的。我认为这在 Windows 上是类似的。但是,如何调用一些更高级别的特定系统例程?比如你如何告诉Windows创建一个窗口?我知道这是由 dll 中的代码处理的,但是在汇编指令级别实际发生了什么? dll中的例程是否通过int指令调用软件中断,或者有什么不同的方法来处理这个?谢谢。

【问题讨论】:

    标签: windows system-calls


    【解决方案1】:

    Windows 不允许您直接调用系统调用,因为系统调用号可以在构建之间更改,如果添加了新的系统调用,其他系统调用可以向前移动,或者如果系统调用被删除,其他系统调用可以向后移动。因此,为了保持向后兼容性,您可以在 DLL 中调用 win32 或本机函数。

    现在有 2 组系统调用,由内核 (ntoskrnl) 和 win32 内核层 (win32k) 提供服务。

    可以从 ntdll.dll 轻松访问内核系统调用存根,而不会导出 win32k 存根,它们在 user32.dll 中是私有的。这些存根包含系统调用号和执行该工作的实际系统调用指令。

    所以如果你想创建一个窗口,你可以在 user32.dll 中调用CreateWindow,然后为了向后兼容调用扩展版本CreateWindowEx,它调用私有系统调用存根NtUserCreateWindowEx,它调用win32k 窗口管理器中的代码。

    【讨论】:

    • 请在您的文本中添加一些换行符。目前很难阅读。
    【解决方案2】:

    进行 Win32 调用以创建窗口实际上与中断无关。客户端应用程序已与提供调用的 .dll 链接,该调用公开了供链接器使用的地址。由于您询问的是调用机制的区别,因此我将这里的讨论限制在可用于任何应用程序的 Win32 调用,而不是内核级调用或设备驱动程序。在汇编语言级别,它与任何其他函数调用相同,因为大多数 Win32 调用都是用户级调用,它们在内部进行所需的内核调用。链接器提供 Win32 函数的地址作为某种分支指令的目标,具体取决于编译器。

    [编辑] 看起来您对中断和 int 的看法是正确的。向量表。 CodeGuru 有一篇很好的文章,其中包含有关 NT 内核调用如何工作的操作系统详细信息。链接:
    http://www.codeguru.com/cpp/w-p/system/devicedriverdevelopment/article.php/c8035

    【讨论】:

    • 是的,我知道 dll 里面有需要的调用,我写的。但基本上我所要求的一切是:是否有用于以软件中断形式绘制 Windows 系统调用的 dll 例程,或者,如果没有,它如何告诉 Windows 内核创建一个窗口?因为据我所知,由于 ringl evel 限制,您无法从程序运行的空间切换,而不是 int 指令。
    • b-gen-jack-o-neill: AFAIK 内核不负责窗口管理。
    • 在较新的处理器上,使用 sysenter/sysexit 指令而不是使用 INT 指令发出软件中断。概念是一样的,都是切换到内核模式的一种方式。窗口不在内核中进行管理,您不会找到 CreateWindow 系统调用,而是建立在许多其他系统调用之上,包括与其他进程通信 - 例如窗口管理器
    • 哇,我终于接近想要的答案了。因此,我认为您希望操作系统执行的每一项操作都在一个或多个内核调用中表示。因此,根据您编写的内容,有一个在内核模式下运行的窗口管理器进程,您使用 .dll 库与它进行通信,该库包含通过内核调用与 Windows 管理器建立进程间通信的例程?也许,你能给我推荐一些关于这个的好文章吗?谢谢。
    • 好吧,窗口管理器是另一个用户空间进程,对于 GUI 的东西,内核只干预与该进程的实际通信,以及该进程实际显示自身的方式。
    猜你喜欢
    • 2014-09-22
    • 1970-01-01
    • 1970-01-01
    • 2014-01-31
    • 2014-11-21
    • 2012-02-16
    • 2015-01-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多