文章目录
线索栏
- Y86-64如何简化处理程序运行时的"异常"情况?状态码Stat的四个值(AOK, HLT, ADR, INS)分别表示什么?
- 通过sum函数的例子,Y86-64汇编与x86-64汇编有哪些关键区别?(指令能力、代码长度、条件码设置)
- 一个完整的Y86-64程序需要包含哪些部分?如何使用汇编器伪指令(如.pos, .align)来组织代码、数据和栈?
- Y86-64的软件开发工具链包含哪些组件?YAS和YIS分别是什么?它们的作用是什么?
- 如何利用现有指令集来实现一个新的指令(如iaddq)?这体现了处理器设计的什么思想?
笔记栏
1.异常处理
1)简化模型
Y86-64不实现复杂的异常处理程序,仅用状态码Stat 记录异常类型,并停止执行。
2)状态码定义
(1)AOK(1):正常。
(2)HLT(2):执行了halt指令。
(3)ADR(3):试图读写非法内存地址(如越界)。
(4)INS(4):遇到非法指令代码。
2.Y86-64程序示例与对比
1)示例函数
long sum(long *start, long count);计算数组和。
2)Y86-64 vs x86-64 汇编关键区别
| 对比项 | x86-64 (GCC生成) | Y86-64 (手写/教学) | 原因/说明 |
|---|---|---|---|
| 常数加载 | movl $0, %eax | irmovq $0, %r8 rrmovq %r8, %rax | Y86-64算术指令(addq)不能使用立即数,需先用irmovq加载到寄存器。 |
| 内存加法 | addq (%rdi), %rax(1条) | mrmovq (%rdi), %r8 addq %r8, %rax(2条) | Y86-64是Load/Store结构,运算指令只能操作寄存器,需先mrmovq加载。 |
| 条件码设置 | 需要testq %rsi, %rsi | 可直接用subq $1, %rsi | Y86-64的subq指令会设置条件码,故可省略单独的test指令。但循环前需用andq显式设置条件码。 |
| 指令总数 | 较少 | 较多 | 受限于更简单的指令集。 |
3)完整程序结构

(1)代码起始:.pos 0指示代码从地址0开始。
(2)栈设置:初始化栈指针(%rsp),通常指向高地址(如.pos 0x200)。
(3)数据声明:用.quad声明数组,用.align 8确保8字节对齐。
(4)主程序(main):调用函数,然后halt。
(5)函数定义:如sum。
(6)栈空间:预留栈空间。
3.工具链与指令扩展思想
1)Y86-64工具链
(1)YAS(汇编器):将.ys汇编文件翻译成.yo目标代码(ASCII格式,如图4-8),包含地址和指令字节。
(2)YIS(指令集模拟器):模拟执行.yo代码,输出最终状态(PC、Stat、寄存器值),用于调试和验证。
2)指令扩展思想 (练习题4.3隐含)
(1)目标:实现新指令 iaddq V, rB(立即数加寄存器)。
(2)方法:用现有指令序列模拟。例如,iaddq $0x123, %rax可分解为:
①irmovq $0x123, %r8(加载立即数到临时寄存器)
②addq %r8, %rax(相加)
(3)启示:复杂的指令可以由简单的指令序列实现。硬件实现时可将此序列固化,对外表现为一条新指令,这是CISC设计思想的体现。
4.练习题
练习题4.3

用iaddq重写sum:可消除对专用寄存器(%r8, %r9)保存常数的依赖,直接iaddq $1, %rsi等,使代码更紧凑。

练习题4.4

关键:正确处理递归调用------保存返回地址、保存/恢复调用者保存寄存器、更新参数(start+1, count-1)。
步骤:基线条件(count <= 0)、递归调用、计算返回值。

练习题4.5


内循环中,加载值后,判断其符号,若为负则用negq取负后再累加。

练习题4.6

尝试使用cmov指令家族,根据值的符号选择是加原值还是加其相反数,避免显式分支。

总结栏
本节从理论规范(ISA)过渡到实践层面,展示了如何为Y86-64编写程序、处理异常,并引入了支撑其开发的软件工具。
- 异常处理的抽象:Y86-64用简单的Stat码抽象了硬件异常,将复杂的处理简化为"停止执行"。这符合其教学定位,让我们聚焦于主流数据通路和控制流设计。
- 简化ISA的代价与模式:通过sum函数的对比,清晰看到简化指令集带来的代价是代码变长(需更多指令完成相同功能)。同时,Load/Store结构和规整的指令格式成为反复出现的模式,这是后续设计高效数据通路的基础。
- 完整的编程视角:学习编写完整Y86-64程序,使我们意识到除了计算逻辑,还必须关心内存布局(代码、数据、栈的地址安排)。这连接了ISA与后续的链接、加载和操作系统概念。
- 工具链的重要性:YAS和YIS构成了最小但完整的开发环境。汇编器将符号化指令映射为二进制,模拟器则建立了一个可预测的执行沙盒。这是验证处理器设计正确性的关键。
- "实现"与"扩展"的思维:练习题引导我们思考如何用现有指令"实现"新指令,这揭示了指令集的可扩展性以及硬件/软件协同设计的思路------软件模拟的功能,可以由硬件固化来提速。
核心启示:一个指令集体系结构(ISA)的生命力,不仅在于其定义,还在于支持其运行的软件工具链和编程实践。Y86-64虽然简单,但通过亲手编写和调试其汇编程序,我们能深刻体会到指令集设计选择对编程的影响,并为后续理解如何用硬件高效实现这个ISA做好充分准备。从"编程"到"模拟执行"的闭环,是学习处理器体系结构不可或缺的实践环节。