究竟什么是中断?
What exactly is an interrupt?
我想了解我在 Logisim 中的 6502 类工作处理器项目的中断到底是什么。
我知道中断执行以下步骤:
停止处理当前程序
将所有未完成的数据存入堆栈
“有点事”吗
加载未完成的数据,让程序保持运行正常。
我的问题是:在 “某事” 这一步中发生了什么?程序计数器是否被重定向到要执行的特殊程序?比如读取按下按钮的 ASCII 码并将其保存到寄存器或某个内存位置?如果是这样,那个特殊程序通常存储在内存中的什么地方?你能做出这样一个 CPU 来处理不同类型的中断吗?也许如果你按下按钮“a”那么它的ASCII将存储在A寄存器中,但是如果你按下按钮“b”那么它就会存储在X寄存器中?
非常感谢任何帮助。
编辑:感谢大家的回答。我学到了很多,现在可以继续我的项目了。
我猜你要求硬件中断(IRQ 或 NMI)。在堆栈的第 2 步(不在堆栈寄存器中)存储程序计数器和标志寄存器。稍后您调用 RTI
以恢复程序执行。程序计数器加载"something"的起始地址,这是中断子程序或处理中断的程序。如果需要修改它们的值并在 RTI 之前恢复它们,它必须存储 A,X,Y 寄存器。 IRQ 中断可以用 I
标志屏蔽(延迟),NMI 是不可屏蔽的,即它总是被处理。他们有不同的子程序地址。
My question is: what happens during that "SOMETHING" step? Does the program counter get redirected to a special program to be executed?
6502 可屏蔽中断发生的情况是这样的:
- 产生中断(我的意思是芯片上的中断引脚被强制拉低。
- 当需要执行新指令时,6502 检查中断引脚是否为低电平以及状态寄存器中的中断屏蔽是否未设置。如果不是这种情况,即如果中断引脚为高电平或中断屏蔽为高电平,CPU 将继续。
- 假设需要中断,CPU 将 PC 保存在堆栈中
- 然后 CPU 将状态寄存器保存在堆栈中,但
B
位设置为 0。B
位是 "break" 位。对于 BRK
指令,它将设置为 1,这是区分硬件中断和 BRK
指令的唯一方法。
- 然后 CPU 获取位置
$FFFE
和 $FFFF
的地址并将其填充到 PC 中,因此从该地址再次开始执行。
仅此而已。其他一切都取决于程序员,直到程序员执行 RTI
,然后状态字和 return 地址被拉出堆栈并恢复到各自的寄存器中。保存任何寄存器和其他数据是程序员的责任。
Does the program counter get redirected to a special program to be executed? Something like reading the pressed button's ASCII code and saving that into a register or some memory location?
没错。在基于6502的计算机系统中,内存顶部有三个向量:
$FFFA - $FFFB
:不可屏蔽中断(除状态寄存器中的 I
位被忽略外,同上)。
$FFFC - $FFFD
:CPU检测到复位时使用的复位向量
$FFFE - $FFFF
: 正常中断向量。
以上内容通常在 ROM 中,因为 CPU 上电时复位向量(至少)必须存在。每个地址都将指向机器操作系统中用于处理中断的例程。
通常,中断例程将首先通过存储在 RAM 中的向量进行间接跳转。这允许在机器 运行 时更改中断例程。
然后中断例程必须确定中断源。例如,在 Commodore PET 上,中断可能源自 VIA 芯片或 PIA 芯片中的任何一个,并且每个芯片都可能由于各种原因引发中断,例如当显示器出现垂直空白时,即当它完成扫描屏幕并返回顶行时,其中一个 PIA 芯片会引发中断。在此中断期间,PET 执行一个程序来扫描键盘和另一个程序来反转光标。当 VIA 定时器归零时,可能会发生另一个中断,程序员可以插入中断例程,例如切换输出线以生成声音方波。
评论中的一些问题解答。
program counter goes to address $FFFE to get relocate to the address
不,程序计数器设置为该地址处的任何值。如果你有:
FFFE: 00
FFFF: 10
程序计数器将设置为 00
(6502 是小端),这是中断例程必须开始的地方。此外,NMI 的向量位于 $FFFA
。普通中断与BRK
指令共享$FFFE
,而不是NMI。
What exactly the reset vector does? Does it reset the cpu?
重置向量包含在处理器启动后或发生重置时运行的代码的位置。
What's the difference between NMI and IRQ? Then I also would like to know what's up with masking? Is it the way to set the "I" flag in Processor Status Register high or low?
6502 状态寄存器包含七个标志。它们主要与算术指令的结果有关,例如如果运算结果为零,则设置 Z,当运算溢出八位并进行移位时,设置 C。 I 标志启用和禁用正常中断 (IRQ)。如果它为零,则 IRQ 中断将得到遵守。如果它是 1,中断被禁用。您可以使用 SEI
和 CLI
指令手动设置和禁用它,并在发生中断时自动设置它(这是为了防止中断中断)。
NMI 是一个不可屏蔽的中断。不同之处在于它忽略了 I 标志的状态并使用了不同的向量。
And finally, what are vectors? Are they synonymous for indirect addresses?
是的。
Oh, and if you do know, how are interrupt addresses starting from $FFFA stored in ROM instead of RAM in real 6502?
您必须安排地址解码逻辑将这些地址指向 ROM 而不是 RAM。事实上,在 Commodore 系统中,$F000
的整个块是包含部分操作系统的 ROM。这同样适用于大多数其他基于 6502 的系统。
6502有四种中断类型:RESET、NMI、IRQ和BRK。前三个是硬件中断,最后一个是软件中断。硬件中断在微处理器本身的引脚上具有物理输入电压。软件中断是由BRK指令引起的。
所有中断都是'vectored'。这意味着当它们出现时,程序计数器 (PC) 会立即从存储在内存中的地址加载,并从该地址继续执行指令。
地址以两字节小端格式存储在 64k 内存的末尾space。它们是(十六进制):
NMI $FFFA/$FFFB
RESET $FFFC/$FFFD
IRQ $FFFE/$FFFF
BRK $FFFE/$FFFF
在 NMI、IRQ 和 BRK 的情况下,当前 PC 地址被压入堆栈,然后再加载中断地址。处理器状态寄存器也被压入堆栈。
将寄存器压入堆栈,足以在中断服务(处理)后恢复执行。但是,A、X 和 Y 寄存器不会自动压入堆栈。相反,中断服务例程应该在必要时执行此操作 - 并在服务结束时将它们从堆栈中拉回。
注意 IRQ 和 BRK 向量具有相同的地址。为了区分您的服务代码中发生了什么,您需要检查推送的处理器状态寄存器的 Break Bit。如果中断来自 BRK 指令,则设置中断位。
当前正在执行的指令将始终在服务中断之前完成。
中断处理有很多微妙之处。其中之一是在它们同时发生(断言)的情况下哪种类型的中断获胜。另一个是在指令周期内发生中断的点。如果中断发生在指令的倒数第二个周期之前,那么它将在下一条指令中得到服务。如果在倒数第二个周期或之后,那么它会延迟到一个指令之后。
IRQ 中断可以 'switched off' 或通过使用 SEI 指令在处理器状态寄存器中设置一个位来忽略。
通常中断服务例程需要确定中断的原因(磁盘驱动器、键盘等)并确保清除中断条件并执行任何处理(例如将按键输入缓冲区)。它通常可以通过 reading/writing 映射到硬件的特定内存位置来做到这一点。
这里有更多信息link:https://www.pagetable.com/?p=410
关于中断如何在真正的 8 位机器中工作的更多信息(第 59、86、295 页):BBC Microcomputer Advanced User Guide
以及有关物理芯片封装的更多信息,您可以在芯片封装本身上看到 NMI、RES(ET) 和 IRQ 引脚(第 2,3 页):6502 Datasheet
中断是通过硬件或软件向运行处理器发出信号,使处理器注意该动作并根据中断消息执行动作。
中断分为三种:
- 内部中断:- 包括时钟周期中断,其中cpu必须执行特定操作直到特定时间并且必须去执行另一个操作。
- 软件中断:- 当软件本身出现问题或错误时,会发生此中断。例如,用户试图将某物除以零,然后发生错误。还有中断。
- 外部中断:- 外部中断是由 IO 设备引起的,例如鼠标和键盘。
Cpu就是为了处理这种类型的中断而设计的,并在中断发生之前恢复进程。
我想了解我在 Logisim 中的 6502 类工作处理器项目的中断到底是什么。 我知道中断执行以下步骤:
停止处理当前程序
将所有未完成的数据存入堆栈
“有点事”吗
加载未完成的数据,让程序保持运行正常。
我的问题是:在 “某事” 这一步中发生了什么?程序计数器是否被重定向到要执行的特殊程序?比如读取按下按钮的 ASCII 码并将其保存到寄存器或某个内存位置?如果是这样,那个特殊程序通常存储在内存中的什么地方?你能做出这样一个 CPU 来处理不同类型的中断吗?也许如果你按下按钮“a”那么它的ASCII将存储在A寄存器中,但是如果你按下按钮“b”那么它就会存储在X寄存器中?
非常感谢任何帮助。
编辑:感谢大家的回答。我学到了很多,现在可以继续我的项目了。
我猜你要求硬件中断(IRQ 或 NMI)。在堆栈的第 2 步(不在堆栈寄存器中)存储程序计数器和标志寄存器。稍后您调用 RTI
以恢复程序执行。程序计数器加载"something"的起始地址,这是中断子程序或处理中断的程序。如果需要修改它们的值并在 RTI 之前恢复它们,它必须存储 A,X,Y 寄存器。 IRQ 中断可以用 I
标志屏蔽(延迟),NMI 是不可屏蔽的,即它总是被处理。他们有不同的子程序地址。
My question is: what happens during that "SOMETHING" step? Does the program counter get redirected to a special program to be executed?
6502 可屏蔽中断发生的情况是这样的:
- 产生中断(我的意思是芯片上的中断引脚被强制拉低。
- 当需要执行新指令时,6502 检查中断引脚是否为低电平以及状态寄存器中的中断屏蔽是否未设置。如果不是这种情况,即如果中断引脚为高电平或中断屏蔽为高电平,CPU 将继续。
- 假设需要中断,CPU 将 PC 保存在堆栈中
- 然后 CPU 将状态寄存器保存在堆栈中,但
B
位设置为 0。B
位是 "break" 位。对于BRK
指令,它将设置为 1,这是区分硬件中断和BRK
指令的唯一方法。 - 然后 CPU 获取位置
$FFFE
和$FFFF
的地址并将其填充到 PC 中,因此从该地址再次开始执行。
仅此而已。其他一切都取决于程序员,直到程序员执行 RTI
,然后状态字和 return 地址被拉出堆栈并恢复到各自的寄存器中。保存任何寄存器和其他数据是程序员的责任。
Does the program counter get redirected to a special program to be executed? Something like reading the pressed button's ASCII code and saving that into a register or some memory location?
没错。在基于6502的计算机系统中,内存顶部有三个向量:
$FFFA - $FFFB
:不可屏蔽中断(除状态寄存器中的 I
位被忽略外,同上)。
$FFFC - $FFFD
:CPU检测到复位时使用的复位向量
$FFFE - $FFFF
: 正常中断向量。
以上内容通常在 ROM 中,因为 CPU 上电时复位向量(至少)必须存在。每个地址都将指向机器操作系统中用于处理中断的例程。
通常,中断例程将首先通过存储在 RAM 中的向量进行间接跳转。这允许在机器 运行 时更改中断例程。
然后中断例程必须确定中断源。例如,在 Commodore PET 上,中断可能源自 VIA 芯片或 PIA 芯片中的任何一个,并且每个芯片都可能由于各种原因引发中断,例如当显示器出现垂直空白时,即当它完成扫描屏幕并返回顶行时,其中一个 PIA 芯片会引发中断。在此中断期间,PET 执行一个程序来扫描键盘和另一个程序来反转光标。当 VIA 定时器归零时,可能会发生另一个中断,程序员可以插入中断例程,例如切换输出线以生成声音方波。
评论中的一些问题解答。
program counter goes to address $FFFE to get relocate to the address
不,程序计数器设置为该地址处的任何值。如果你有:
FFFE: 00
FFFF: 10
程序计数器将设置为 00
(6502 是小端),这是中断例程必须开始的地方。此外,NMI 的向量位于 $FFFA
。普通中断与BRK
指令共享$FFFE
,而不是NMI。
What exactly the reset vector does? Does it reset the cpu?
重置向量包含在处理器启动后或发生重置时运行的代码的位置。
What's the difference between NMI and IRQ? Then I also would like to know what's up with masking? Is it the way to set the "I" flag in Processor Status Register high or low?
6502 状态寄存器包含七个标志。它们主要与算术指令的结果有关,例如如果运算结果为零,则设置 Z,当运算溢出八位并进行移位时,设置 C。 I 标志启用和禁用正常中断 (IRQ)。如果它为零,则 IRQ 中断将得到遵守。如果它是 1,中断被禁用。您可以使用 SEI
和 CLI
指令手动设置和禁用它,并在发生中断时自动设置它(这是为了防止中断中断)。
NMI 是一个不可屏蔽的中断。不同之处在于它忽略了 I 标志的状态并使用了不同的向量。
And finally, what are vectors? Are they synonymous for indirect addresses?
是的。
Oh, and if you do know, how are interrupt addresses starting from $FFFA stored in ROM instead of RAM in real 6502?
您必须安排地址解码逻辑将这些地址指向 ROM 而不是 RAM。事实上,在 Commodore 系统中,$F000
的整个块是包含部分操作系统的 ROM。这同样适用于大多数其他基于 6502 的系统。
6502有四种中断类型:RESET、NMI、IRQ和BRK。前三个是硬件中断,最后一个是软件中断。硬件中断在微处理器本身的引脚上具有物理输入电压。软件中断是由BRK指令引起的。
所有中断都是'vectored'。这意味着当它们出现时,程序计数器 (PC) 会立即从存储在内存中的地址加载,并从该地址继续执行指令。
地址以两字节小端格式存储在 64k 内存的末尾space。它们是(十六进制):
NMI $FFFA/$FFFB
RESET $FFFC/$FFFD
IRQ $FFFE/$FFFF
BRK $FFFE/$FFFF
在 NMI、IRQ 和 BRK 的情况下,当前 PC 地址被压入堆栈,然后再加载中断地址。处理器状态寄存器也被压入堆栈。
将寄存器压入堆栈,足以在中断服务(处理)后恢复执行。但是,A、X 和 Y 寄存器不会自动压入堆栈。相反,中断服务例程应该在必要时执行此操作 - 并在服务结束时将它们从堆栈中拉回。
注意 IRQ 和 BRK 向量具有相同的地址。为了区分您的服务代码中发生了什么,您需要检查推送的处理器状态寄存器的 Break Bit。如果中断来自 BRK 指令,则设置中断位。
当前正在执行的指令将始终在服务中断之前完成。
中断处理有很多微妙之处。其中之一是在它们同时发生(断言)的情况下哪种类型的中断获胜。另一个是在指令周期内发生中断的点。如果中断发生在指令的倒数第二个周期之前,那么它将在下一条指令中得到服务。如果在倒数第二个周期或之后,那么它会延迟到一个指令之后。
IRQ 中断可以 'switched off' 或通过使用 SEI 指令在处理器状态寄存器中设置一个位来忽略。
通常中断服务例程需要确定中断的原因(磁盘驱动器、键盘等)并确保清除中断条件并执行任何处理(例如将按键输入缓冲区)。它通常可以通过 reading/writing 映射到硬件的特定内存位置来做到这一点。
这里有更多信息link:https://www.pagetable.com/?p=410
关于中断如何在真正的 8 位机器中工作的更多信息(第 59、86、295 页):BBC Microcomputer Advanced User Guide
以及有关物理芯片封装的更多信息,您可以在芯片封装本身上看到 NMI、RES(ET) 和 IRQ 引脚(第 2,3 页):6502 Datasheet
中断是通过硬件或软件向运行处理器发出信号,使处理器注意该动作并根据中断消息执行动作。 中断分为三种:
- 内部中断:- 包括时钟周期中断,其中cpu必须执行特定操作直到特定时间并且必须去执行另一个操作。
- 软件中断:- 当软件本身出现问题或错误时,会发生此中断。例如,用户试图将某物除以零,然后发生错误。还有中断。
- 外部中断:- 外部中断是由 IO 设备引起的,例如鼠标和键盘。
Cpu就是为了处理这种类型的中断而设计的,并在中断发生之前恢复进程。