考试时间:2026 年 1 月 17 日 8:30-10:30,最后延长了 10 分钟
考前一天开始复习,由于 16 号在摆烂,17 号才开始正式复习。使用 notebooklm 上传了课本、作业题以及德州卷。抄书抄到晚上九点多才开始看考卷(发现看卷子的时间有点晚 qwq,好多都不会),到第二天凌晨两点一共看了两套卷。考场上差点没做完,但是考卷上出现了往年 PPT 的原题!但是没看到!可恶
当天下午整理的笔记:
ICS-1 指令集部分#
附录 A ,第 655 页
指令的周期:每条指令都得经过 fetch 和 decode
- 取址 fetch
- 译码 decode
- 计算地址 evaluate address
- 取操作数 fetch oprands
- 执行 execute
- 存储 store
- CC:条件码 Conditional Code。执行向通用寄存器写入结果的指令时会自动更新 CC。LEA 指令不设置 CC。
- PSR:用户跳转寄存器 Processor Status Register,记录身份状态。寄存器地址在 xFFFC
- 15 位:特权模式。0 为特权模式,1 为用户模式
- 14 位:中断使能。0 允许终端,1 不允许中断
- 10-8 位:优先级。0 最低,7 最。当外部设备优先级比当前优先级高时,中断才会发生,否则抛弃
- 2-0 位:条件码 CC。设置 NZP。见
- ACV:访问控制违规 Access Control Violation。当 CPU 处于用户模式时如果访问特权内存区域(系统空间 x 0000-x 2 FFF 或 I/O 设备寄存器地址 xFE 00-xFFFF)时,会设置 ACV=1,抛出异常,将 PC 和 PSR 压入系统栈,并跳转到 x 0102 处理异常程序
- BEN:分支使能 Branch Enable。若 nzp 位为 1 则会跳转
LC 3 指令:
- 操作指令:Fetch (8) + Decode (1) + 执行阶段周期 1(只有计算),共 10 周期,会计算 CC
ADD DR SR1 SR2:DR=SR 1 + SR 2 或 imm 5。2 条AND DR SR1 SR2:DR=SR 1 & SR 2 或 imm 5。2 条NOT vDR SR:DR = ~SR
- 数据搬运指令
LD DR PCoffset9:PC 相对寻址加载。DR = mem (PC+sext (offset 9))LDR DR BaseR PCoffset6。基址偏移加载。DR <- mem (baseR + sext (offset 9))LDI DR PCoffset9:间接寻址加载。DR = mem (mem (offset 9 + PC))LEA DR PCoffset9:加载有效访问地址。不访问内存。DR = PC + SEXT (offset 9)ST SR PCoffset9:PC 相对寻址存储。Mem (PC+sext (offset 9)) = SRSTI SR PCoffset9:间接寻址存储。Mem (Mem (PC+sext (offset 9))) = SRSTR SR BaseR PCoffset6:基址偏移存储。Mem (baseR + offset 6) <- SR
- 控制指令
BR nzp PCOffset9: 条件跳转。若 BEN 为真,则 PC = PC+offset 9JMP BaseR:无条件跳转。PC = BaseRRET:无条件跳转。PC = R 7JSR PCoffset11: 子程序调用。R 7 = PC,PC = target(PC+offset 11)JSRR BaseR:子程序调用。R 7 = PC,PC = target(BaseR)TRAP trapvec8:系统调用。R 7=PC, PC = Mem (ZEXT (trapvect 8))。- GETC :x 20,从键盘输入字符存入 R 0
- OUT:x 21,将 R 0 字符输入到显示器
- PUTS:x 22,以 R 0 存储的字符串首地址,输出一个以 null 结尾的字符串
- IN:x 23,打印提示符,读取一个字符并回到显示器,存入 R 0
- HALT:x 25,停机
RTI:恢复 PC 和 PSR。
LC 3 汇编语言伪操作:
- 伪操作:不是机器指令,指导汇编器翻译汇编码为机器代码
.ORIG x3000: 程序从 x 3000 开始执行A .FILL x0006在内存中预留一个位置,标记为 A,填入 6NUMBER .BLKW 10:在内存预留 10 个位置,数组开头标记为 NUMBERHELLO .STRINGZ "Hello":存储字符串.END:源代码汇编结束,停止汇编过程
- 标号:给内存地址起名;注释
- 汇编过程:两遍扫描。第一遍创建符号表,利用位置计数器记录当前的地址,遇到标号时将标号记录到符号表中。第二遍生成机器码,汇编指令翻译成机器码,标号通过符号表转换为偏移量和地址,并处理伪操作
ICS-2 控制信号与数据通路#
这一部分是用 AI 写的
基于您提供的资料,特别是《Introduction to Computing Systems》的附录 C(The Microarchitecture of the LC-3)以及期末复习资料,以下是对 LC-3 中**数据通路(Data Path)和控制信号(Control Signals)**的详细解析。
理解这两者的关键在于:数据通路是处理信息的“工厂设施”(如机器、传送带),而控制信号是“操作指令”(如开启机器、切换开关)。
1. 数据通路 (The Data Path)#
数据通路包含了所有实际处理、存储和传输信息的硬件组件。LC-3 的数据通路设计围绕着一条**全局总线(Global Bus)**展开。
A. 全局总线 (The Global Bus)#
- 结构:LC-3 只有一条共享的 16 位总线。这意味着在任何给定的时钟周期内,只能有一个组件向总线传输数据,但可以有多个组件从总线读取数据。
- 三态门 (Tri-state Devices):为了防止冲突,每个可以向总线发送数据的设备(如 PC, ALU, MDR)前都有一个三态门(三角形图标)。只有当相应的 Gate 信号(如
GatePC)为 1 时,数据才能上总线,。
B. 核心处理组件#
- ALU (算术逻辑单元),:
- 功能:执行加法(ADD)、与运算(AND)、非运算(NOT)和直接传递(PASSA)。
- 输入:有两个输入端 A 和 B。A 端总是来自寄存器(SR 1);B 端可以来自寄存器(SR 2)或者指令中的立即数(通过 SEXT 扩展)。
- 控制:
ALUK信号控制具体的运算类型。
- 寄存器堆 (Register File),:
- 功能:包含 R 0 到 R 7 八个通用寄存器。
- 输入/输出:在一个周期内,可以同时读取两个源寄存器(SR 1, SR 2)并写入一个目的寄存器(DR)。
- 控制:
SR1MUX选择源寄存器地址,LD.REG控制是否写入。
- PC (程序计数器) 与 PCMUX,:
- PCMUX:决定下一个 PC 的值。
- 输入源:
PC + 1:顺序执行。BUS:用于 JMP, JSR 等指令直接加载地址。ADDER:来自地址加法器的输出(用于 BR 跳转计算)。
- MAR (内存地址寄存器) 与 MDR (内存数据寄存器):
- 它们是 CPU 与内存/IO 交互的接口。
- MARMUX:决定放入 MAR 的地址来源(是来自 IR 的零扩展,还是来自地址加法器)。
- 地址加法器:
- 专门用于计算地址(如
PC + offset或BaseR + offset),不占用 ALU 资源。
- 专门用于计算地址(如
2. 控制信号 (Control Signals)#
控制信号由**控制单元(有限状态机 FSM)**产生,用于指挥数据通路中的组件在每个时钟周期该做什么。控制信号主要分为三类:
A. 门控信号 (Gate Signals) - “谁在说话”
控制谁有权将数据放到全局总线上。在任意时刻,必须且只能有一个 Gate 信号为 1(除了总线空闲时)。
GatePC:将 PC 的值放到总线上。GateMDR:将 MDR 的值放到总线上(通常用于取指或读取数据)。GateALU:将 ALU 的计算结果放到总线上。GateMARMUX:将地址计算结果放到总线上(例如JSR保存返回地址时)。
B. 加载信号 (Load Signals / LD. Xx) - “谁在听”
控制哪个寄存器将从总线或其他来源捕获数据。在时钟周期的末尾生效。
LD.REG:将总线上的数据写入 DR 指定的寄存器。LD.IR:将总线数据(指令)写入指令寄存器。LD.PC:更新 PC 的值。LD.MAR/LD.MDR:更新内存接口寄存器。LD.CC:根据总线上的数据更新条件码(N, Z, P)。
C. 选择信号 (MUX Selectors) - “怎么走”
控制多路选择器(MUX)选择哪一路输入。
PCMUX:选择下一条指令地址的来源(PC+1, 总线, 还是 Adder)。SR1MUX/SR2MUX:选择源操作数寄存器。SR2MUX尤其重要,用于选择第二个操作数是来自寄存器(如ADD R0,R1,R2)还是立即数(如ADD R0,R1,#5),。ADDR1MUX/ADDR2MUX:控制地址加法器的输入(是 PC 还是 BaseR?是 offset 6 还是 offset 9?),。ALUK:虽不是 MUX,但类似选择信号,选择 ALU 执行的操作(ADD/AND/NOT/PASSA)。
3. 控制单元与微操作#
控制信号不是随机产生的,而是由一个**有限状态机(FSM)**管理的。LC-3 的 FSM 定义了计算机在每个时钟周期的行为。
- 状态 (State):每一个状态对应一个时钟周期。每个状态都有一组特定的控制信号输出(这被称为微指令)。
- 状态转换:由微序列器 (Microsequencer) 决定下一个状态是什么。
- 取指阶段 (Fetch):所有指令都从状态 18 开始(MAR<-PC),接着状态 33,状态 28(读内存),状态 30(加载 IR),最后到状态 32(译码)。
- 译码 (Decode):在状态 32,根据
IR[15:12](操作码),微序列器决定跳转到哪个特定指令的执行序列。
- 决策信号:微序列器根据以下信号决定下一状态:
INT:是否有中断请求。R:内存是否读写完毕(Ready bit)。BEN(Branch Enable):是否满足分支跳转条件。ACV:是否有访问权限违规。
4. 实例分析:ADD 指令的执行#
以 ADD R1, R2, R3 为例,在执行阶段(Execute Phase),控制信号如下配合:
- 取操作数:
SR1MUX选择 R 2。SR2MUX选择 R 3(因为 IR=0)。
- 运算:
ALUK设置为ADD(00),让 ALU 执行加法。
- 输出结果:
GateALU= 1,将结果放到总线上。
- 保存结果:
DR指向 R 1。LD.REG= 1,在周期末尾将总线数据写入 R 1。LD.CC= 1,同时更新条件码。
总结#
LC-3 的运行本质上就是数据通路在控制信号的指挥下,在状态机的驱动中,通过总线不断搬运和计算数据的过程。每条指令的执行就是在一个个特定的状态中,打开特定的 Gate,设置特定的 MUX,并拉高特定的 LD 信号。
ICS-3 微指令表#
LC-3 的微指令表(Microinstruction Table),也被称为控制存储(Control Store),是 LC-3 微架构的核心部分。它定义了计算机在每一个机器状态(State)(即每一个时钟周期)下具体要做什么。
在 LC-3 的微程序实现中,每一个状态对应控制存储中的一行,这一行被称为一条微指令(Microinstruction)。每条微指令由 52 位的二进制信号组成,它们直接控制着计算机的硬件行为。
以下是微指令表的详细构成与逻辑解析:
1. 微指令的总体结构#
每一条微指令(即表中的每一行)包含 52 个比特位,分为两大类功能区域:
- 数据通路控制信号(42 bits):控制数据在硬件组件之间的流动和处理(例如:打开哪个门、选择哪个 MUX 输入、是否写入寄存器)。
- 微序列器控制信号(10 bits):决定下一个时钟周期跳转到哪个状态(即下一条微指令的地址)。
2. 数据通路控制信号#
这 42 个信号直接连接到硬件电路,指挥具体操作。根据功能可细分为以下几类:
A. 加载信号#
决定各个寄存器在当前周期结束时是否更新值。
- LD. PC, LD. IR, LD. MAR, LD. MDR:控制 PC, IR, MAR, MDR 的写入。
- LD. REG:控制通用寄存器(R0-R7)的写入。
- LD. CC, LD. BEN:控制条件码(N, Z, P)和分支使能信号的更新。
- LD. Priv, LD. Priority:控制处理器状态寄存器(PSR)中特权模式和优先级的更新。
B. 门控信号#
控制三态门,决定谁有权将数据发送到全局总线(Global Bus)。在任意时刻,最多只能有一个 Gate 信号为 1。
- GatePC:PC 的值上总线。
- GateMDR:MDR 的值上总线。
- GateALU:ALU 的计算结果上总线。
- GateMARMUX:地址计算结果上总线(如
JSR保存返回地址时)。 - GateVector, GatePSR, GateSP:用于中断/异常处理时将向量、PSR 或栈指针上总线。
C. 多路选择器信号#
控制数据通路中的选择器,决定数据的来源。
- PCMUX (2 bits):选择 PC 的下一值来源(
PC+1, 总线BUS, 或地址加法器ADDER)。 - DRMUX (2 bits) / SR1MUX (2 bits):选择目标寄存器(DR)或源寄存器(SR1)的地址来源(是指令中的
IR[11:9],IR[8:6], 还是固定的R7或R6/SP)。 - ADDR1MUX (1 bit) / ADDR2MUX (2 bits):控制地址加法器的输入(例如基址寄存器 BaseR 或 PC;偏移量 offset6 或 offset9 等)。
- MARMUX (1 bit):决定写入 MAR 的地址是来自指令的零扩展(ZEXT)还是地址加法器。
D. 功能控制#
- ALUK (2 bits):命令 ALU 执行什么运算(
ADD,AND,NOT, 或PASSA)。 - MIO. EN / R.W:控制内存或 I/O 的读写操作。
3. 微序列器控制信号#
这 10 个信号决定了状态机的跳转逻辑,即“下一状态地址”是如何生成的:
- IRD (1 bit):指令解码信号。
- 如果 IRD=1,下一状态地址直接由当前指令的操作码(Opcode)决定(跳转到各指令的第一步,如
ADD跳到状态 1)。这是状态 32(Decode)特有的信号。 - 如果 IRD=0,下一状态由
J字段和COND字段决定。
- 如果 IRD=1,下一状态地址直接由当前指令的操作码(Opcode)决定(跳转到各指令的第一步,如
- COND (3 bits):条件跳转选择。选择依据什么条件来修改下一状态地址。
COND1(Memory Ready):检查内存是否读写完成(R bit)。COND2(Branch):检查是否满足分支条件(BEN)。COND3(Addressing Mode):检查寻址模式(如指令的第 11 位)。
- J (6 bits):基础跳转地址。指定默认的下一个状态编号(0-63)。如果满足特定
COND条件,硬件逻辑会修改这个地址的特定位,从而实现状态跳转。
4. 实例分析:FETCH 阶段的微指令#
以所有指令共用的 状态 18 (Fetch 第一步) 为例,其微指令表中的关键信号配置如下:
| 信号类别 | 设置值 | 解释 |
|---|---|---|
| GatePC | 1 | 将 PC 的值放到总线上。 |
| LD. MAR | 1 | 将总线上的值(原 PC)加载到 MAR,准备读内存。 |
| PCMUX | PC+1 | 选择 PC+1 作为 PC 的新值。 |
| LD. PC | 1 | 更新 PC 为 PC+1。 |
| MEM. EN | 0 | 本周期不读写内存(下一周期才读)。 |
| Next State | 33 | J=33 (100001),无条件跳转到状态 33。 |
5. 总结#
LC-3 的微指令表本质上是一个 59 行 × 52 列 的二进制矩阵(Control Store)。
- 列(Columns):代表硬件的控制线(如
LD.REG)。 - 行(Rows):代表状态机的状态(如 State 18)。
- 内容:每一位的
0或1决定了在该时钟周期内,硬件电路是“开启”还是“关闭”,从而组合出宏观的指令行为(如ADD,LDR)。
理解这张表,就理解了计算机是如何将抽象的汇编指令转化为具体的电流脉冲来操纵硬件的。
ICS-4 中断异常与 IO#
数据结构:
- 栈:用 R6 作为栈指针(Stack Pointer),往内存减小的地方增长。
- PUSH 进栈:
ADD R6, R6, -1, 再STR R0, R6, #0,将 R0 进栈 - POP 出栈:
LDR R0, R6, #0, 再ADD R6, R6, #1, 弹出栈顶元素并存入 R0
- PUSH 进栈:
- 队列:使用 FRONT(第一个元素之前) 和 REAR(最近加入的那个元素) 指针,循环队列。入队:REAR 指针+1,STR 入数据。出队:FRONT 指针+1。
循环:使用计数器(for)或者哨兵控制(while)
子程序调用:用 JSR 或 JSRR 寻址,将 PC 保存在寄存器 R7 中,保存寄存器(caller-save)至下次调用。使用 RET(JMP R7)返回子程序。
用户栈和系统栈:
- 入栈保护:发生中断异常或 TRAP 指令时 LC3 会把当前 PSR 和 PC 压入系统栈中。遇到 RTI 指令会弹出当前 PC 和 PSR 并恢复。
- 栈指针设置为 R6。特权模式 R6 是 SSP,用户模式 R6 是 USP。模式切换时,用 Saved_SSP 和 Saved_USP 来寄存和恢复 R6
- 用户栈和系统栈:用户栈里,函数创建栈帧,里边包含函数参数、返回值空间、返回地址(R7),旧的栈指针(R5),局部变量等
- PSR:用户跳转寄存器 Processor Status Register,记录身份状态。寄存器地址在 xFFFC
- 15 位:特权模式。0 为特权模式,1 为用户模式
- 14 位:中断使能。0 允许终端,1 不允许中断
- 10-8 位:优先级。0 最低,7 最。当外部设备优先级比当前优先级高时,中断才会发生,否则抛弃
- 2-0 位:条件码 CC。设置 NZP。
调用函数:运行时栈
- 调用者准备:将参数从右往左压入运行时帧中,第一个参数在最顶端。使用
JSR和JSRR跳转到函数地址。这两个指令会自动保存跳转前地址到 R7 方便链接。 R6 是栈指针,R5 是帧指针 - 被调用者建立栈帧:
- 预留返回值空间
ADD R6, R6, #-1 - 保存返回地址到 R7
ADD R6, R6, #-1,STR R7, R6, #0 - 保存旧栈指针 R5
ADD R6, R6, #-1,STR R5, R6, #0,方便恢复调用者的环境 - 设置新栈指针 R5
ADD R5, R6, #-1,在 R6 上面,是第一个局部变量的位置。 - 分配局部变量空间:有 N 个局部变量则栈指针下移 N 位
ADD R6, R6, #-N
- 预留返回值空间
- 执行代码:
- 加载局部变量:
LDR Rx, R5, -0--,将 R5 上面的局部变量加载到寄存器中 - 加载参数:
LDR Rx, R5, 4++,将 R5 下面 4 位(前 1-3 位分别是旧栈、返回时指针、返回时空间)开始的参数依次存入寄存器中 - 运行程序
- 加载局部变量:
- 被调用者返回:
- 写入返回值:
STR R0, R5, #3,将 R0 写入返回值空间里 - 弹出局部变量:
ADD R6, R5, #1,将 R6 移到旧 R5 的位置 - 恢复旧栈指针:
LDR R5, R6, #0,ADD R6, R6, #1 - 恢复返回地址:
LDR R7, R6, #0,ADD R6, R6, #1 - 执行 RET(JMP R7)
- 写入返回值:
- 调用者清理:此时 R6 指向返回值
- 读取返回值:
LDR R0, R6, #0 - 弹出返回值:
ADD R6, R6, #1 - 弹出参数:
ADD R6, R6, #M,如果有 M 个参数的话
- 读取返回值:
在用户栈中,建立栈帧后,R5 + 0 指向第一个局部变量,R5-1 指向第二个。R5+1 是 saved R5,R5+2 是 saved R7。R5+3 是 return value。R5+4 是传进来的第一个参数。
中断与轮询:
- 内存映射 I/O:LC-3 通过假装读写内存(I/O 映射空间 xFE00 到 xFFFF)来控制外设。
- KBSR(xFE00): 寄存键盘状态。Bit15 是 Ready 位,为 1 时表示有按键输入。Bit14 是中断使能位,为 1 时表示允许键盘向 CPU 发送中断请求。
- KBDR(xFE02):寄存键盘数据。7-0 位为键盘的 ASCII 码。
- DSR(xFE04)显示状态寄存器,有 ready 位和中断使能位(IE, Interrupt Enable);DDR(xFE06)显示数据寄存器
- PSR(xFFFC)处理器状态寄存器
- MCR(xFFFE)机器控制寄存器,控制时钟启动/停止
- 轮询:不断读取 KBSR 和 DSR,效率低
- 中断:异步操作
- 中断触发:当设备 Ready Bit 为 1,OS 设置的 IE 为 1 时,如果设备的优先级 PL 高于当前 CPU 优先级,则 CPU 相应中断。
- CPU 响应:根据状态机,PC 自增后,fetch 前会检查 INT 信号。若有请求,则 CPU 从 USP 跳转到 SSP(通过 R6, Saved_USP 和 Saved_SSP),将当前 PSR 和 PC 压入栈,并修改 PSR bit15 进入特权模式
- 查找中断向量表(x01xx),跳转 PC 到中断服务例程 ISR
- 例程执行完后, RTI 返回,弹出原来的 PSR 和 PC,继续执行刚才没执行的程序。
内存映射:Memory Map
| 地址范围 | 区域名称 | 访问权限 | 备注 |
|---|---|---|---|
| x0000 - x00FF | TRAP 向量表 | 特权 (Supervisor) | 存放 TRAP 服务例程入口地址 |
| x0100 - x01FF | 中断向量表 | 特权 (Supervisor) | 存放中断/异常服务例程入口地址 |
| x0200 - x2FFF | 操作系统/系统栈 | 特权 (Supervisor) | OS 代码、数据、SSP |
| x3000 - xFDFF | 用户空间 | 用户 (User) | 用户程序、数据、USP |
| xFE00 - xFFFF | I/O 映射页 | 特权 (Supervisor) | 设备寄存器 (KBSR, DDR 等) |