Events 事件侦听器的实现——汇编语言与高级语言

Events 事件侦听器的实现——汇编语言与高级语言,events,assembly,operating-system,interrupt,Events,Assembly,Operating System,Interrupt,组装: 考虑一下这个问题。要处理中断(例如来自键盘),只需让键盘将“INT”引脚拉高,并在数据总线上放置一个“vector”。该向量指向汇编程序代码中中断服务例程(ISR)的位置。有关更多详细信息,请参阅 高级语言: 考虑附加事件侦听器的概念。例如,考虑一下。安: 当“demo”元素处于焦点时按下一个键时,myFunction被调用 关系: 附加事件侦听器的概念与在程序集中安装ISR的概念有何关系 我假设直接响应键盘中断的函数是1)操作系统内核的一部分,2)是用C编写的(这些假设正确吗?) 用户

组装:

考虑一下这个问题。要处理中断(例如来自键盘),只需让键盘将“INT”引脚拉高,并在数据总线上放置一个“vector”。该向量指向汇编程序代码中中断服务例程(ISR)的位置。有关更多详细信息,请参阅

高级语言:

考虑附加事件侦听器的概念。例如,考虑一下。安:

当“demo”元素处于焦点时按下一个键时,
myFunction
被调用

关系:


附加事件侦听器的概念与在程序集中安装ISR的概念有何关系

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

用户程序如何告知此操作系统中断处理程序在中断时向其发出警报?当操作系统函数处理中断时,它是否保留一个可变大小的回调函数列表?然后
addEventListener
是否将用户回调函数附加到操作系统函数的列表中


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

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

  • 键盘(硬件层)
  • USB控制器(硬件层)
  • USB控制器驱动程序(内核层)
  • USB通用驱动程序(内核层)
  • HID通用驱动程序(内核层)
  • HID键盘驱动程序(内核层)
  • OS UI事件处理(内核/用户层)
  • 浏览器UI事件循环(用户层)
  • 浏览器UI事件处理程序(用户层)
  • JavaScript引擎事件处理程序(用户层)
  • keydown
    事件侦听器(用户层)
大多数情况下,你的假设都不成立。特别是没有键盘中断。相反,这里有一个USB中断,但它并不像你想象的那样工作。当您按下USB键盘上的某个键时,不会导致向计算机发送消息并生成中断。相反,键盘将按键添加到其内部队列中,并等待计算机对其进行轮询

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

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

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

一旦UI事件循环获得一个键盘事件,它就被传递到浏览器的键盘事件处理程序,然后该处理程序将把它传递给JavaScript引擎。然后,引擎将执行分配为
按键下的
事件侦听器的功能。引擎可能有自己的事件队列,因为JavaScript事件通常一次只处理一个


除了内核中作为中断和系统调用的登陆点的少量代码之外,这些代码都不会在汇编中编写,然后再调用实际分派中断和系统调用的C代码。

Yup,用户空间中的异步回调函数或信号处理程序与运行在裸机上的程序的中断处理程序非常相似。(例如,现代硬件上的内核,或任何独立程序)Javascript有点特殊,因为作为一种托管语言,VM知道何时可以安全地异步运行某些东西;内核中有几层软件。(抱歉,我没有时间写一些值得发表的东西作为回答。)“附加事件侦听器的概念与在汇编中使用ISR的概念有什么关系?”。。。从操作系统内核的角度来看,事件处理程序/侦听器通常是非中断的“业务逻辑代码”,这是在中断服务完成后在主线程中完成的事情。你不必以任何快速的方式处理事件处理程序,它们可以等待几微秒,不会发生可怕的事情,而且操作系统通常只会将主事件委托给用户应用程序,在那里运行事件循环,处理事件,跟踪自己的侦听器并调用它们(例如android)。与8080的关系更像是键盘中断过程。键盘将按键输入缓冲区(中断部分),然后运行的代码将
document.getElementById("demo").addEventListener("keydown", myFunction);

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