events - 事件监听器的实现——汇编与高级语言

标签 events assembly operating-system interrupt

程序集:

考虑 Intel 8080 .要处理中断(例如来自键盘),您只需让键盘将“INT”引脚拉高并在数据总线上放置一个“向量”。该向量指向中断服务例程 (ISR) 在汇编程序代码中的位置。参见 this answer了解更多详情。

高级语言:

考虑附加事件监听器的概念。例如考虑 Javascript's keydown event listener .一个example :

document.getElementById("demo").addEventListener("keydown", myFunction);

function myFunction() {
    document.getElementById("demo").style.backgroundColor = "red";
}

当“demo”元素处于焦点状态时按下某个键时,将调用 myFunction

关系:

附加事件监听器的概念与在汇编中具有 ISR 的概念有何关系?

我假设直接响应键盘中断的函数是 1) 操作系统内核的一部分和 2) 用 C 编写的。(这些假设是否正确?)

用户程序如何告诉这个操作系统中断处理程序在中断时提醒它?操作系统函数是否保留可变大小的函数列表以在处理中断时回调?然后 addEventListener 是否将用户回调函数附加到 OS 函数的列表中?

注意:我特别选择 Intel 8080 作为示例,因为与现代 CPU 相比,它没有辅助操作系统相关功能的奇特功能。

最佳答案

从按下一个键到运行 JavaScript keydown 事件监听器中的代码,这是一个漫长而复杂的过程。假设一个 USB 键盘,通过硬件和软件层的路径是这样的:

  • 键盘(硬件层)
  • USB Controller (硬件层)
  • USB Controller 驱动(内核层)
  • USB通用驱动(内核层)
  • HID 通用驱动程序(内核层)
  • HID键盘驱动(内核层)
  • OS UI 事件处理(内核/用户层)
  • 浏览器 UI 事件循环(用户层)
  • 浏览器 UI 事件处理程序(用户层)
  • JavaScript 引擎事件处理程序(用户层)
  • keydown 事件监听器(用户层)

其中大部分内容并不像您假设的那样有效。特别是没有键盘中断。相反,有一个 USB 中断,但它并不像您想象的那样工作。当您按下 USB 键盘上的某个键时,不会将消息发送到计算机并生成中断。相反,键盘将按键按下添加到其内部队列并等待计算机对其进行轮询。

这是因为USB通信完全由USB主机(电脑)调度。除非响应主机的请求,否则 USB 设备不允许在总线上通信。由于 USB 事务被安排在一毫秒的帧中,通常操作系统只会每毫秒轮询一次 USB 键盘,要求它报告自上次轮询设备以来发生的任何事件。只有当键盘响应这个请求时(或者可能当帧中所有预定的传输都完成时),USB Controller 才会产生中断。

键盘的响应将采用 HID (Human Interface Device) 的形式报告。 HID 堆栈将对其进行解码以查看报告了哪些键盘事件,并将它们转换为所有键盘类型通用的格式。这将由操作系统中的某种用户界面层(例如 Windows 上的“Win32”API 层,或 Linux 上的 X 服务器)进一步处理,然后放入浏览器的 UI 事件队列中。

浏览器不会因为按键被按下而“中断”。相反,浏览器将有一个主 UI 界面事件循环,并且事件将只在程序中的单个定义点一次处理一个。这个循环所做的就是从 UI 事件队列中提取事件并将它们分派(dispatch)到浏览器中的适当代码。当队列为空时(通常几乎所有时间),循环只是等待一个事件。在等待期间,事件循环的线程未被操作系统调度,也未在任何 CPU 上运行。

一旦 UI 事件循环获得键盘事件,它就会传递给浏览器的键盘事件处理程序,然后由浏览器的键盘事件处理程序将其传递给 JavaScript 引擎。然后引擎将执行指定为 keydown 事件监听器的函数。引擎可能有自己的事件队列,因为 JavaScript 事件通常也一次只处理一个。

除了在调用实际调度它们的 C 代码之前充当中断和系统调用的着陆点的内核中的少量代码外,这些都不会用汇编编写。

关于events - 事件监听器的实现——汇编与高级语言,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51238247/

相关文章:

java - 合作调度与抢占式调度?

javascript - 使用可拖动交互时检测晃动

events - 在 JTable 中移动列时是否会调用事件?

javascript - 在函数中运行代码就像在另一个作用域中运行一样

c++ - 与裸 __m128 相比,SSE vector 包装器类型的性能

memory-management - 段的静态重定位或静态重定位是什么意思

c# - 事件发送者在客户端的事件处理程序代码中被处置

linux - "Hello World"函数不使用 C printf

c - 第三阶段二元炸弹组装

python - 调用操作系统打开网址?