资讯详情

资讯详情

读8086手册:从引脚时序到最小系统与中断向量表实战

简介Intel 8086手册PDF版是一份学习十六位微处理器架构与接口技术的经典参考资料适合计算机专业学生、嵌入式开发者和硬件工程师阅读。手册针对8086/8086-2/8086-1三个型号系统介绍了HMOS-III工艺下的5、8、10MHz三种时钟版本并围绕1MB直接寻址能力、14个16位寄存器、24种操作数寻址模式等核心特性展开覆盖位、字节、字、块操作以及8位/16位有符号与无符号二进制或十进制运算。文中还重点说明了40引脚封装、最小与最大工作模式、MULTIBUS系统兼容接口以及AD15-AD0、BHE等关键引脚的时序行为适合用于课程设计、实验对照或底层驱动开发前的原理梳理。资源包仅含1个PDF文件大小约629KB内容排版清晰便于检索目前页面已有622人学习下载也侧面说明其在微机原理学习中的实用价值。1. 一块 Intel 8086 芯片手册才是那个最该先读完的文档拿到一块 Intel 8086很多人第一反应是找例程、找开发板资料、问群里有没有现成代码。我见过不少人在没有文档的情况下硬猜引脚结果地址线接反、锁存器选错、中断向量表写到 ROM 里去系统上电就翻车。8086 手册不是拿来垫桌脚的它回答了这类芯片开发里最核心的三个问题引脚怎么接、指令怎么编、总线时序怎么对。这篇笔记就是按这个顺序把「读手册 → 搭硬件 → 写启动代码 → 调时序 → 验真」这条路径完整走一遍。适合正在做计算机组成实验、维护老平台、或者想从底层理解 x86 的开发者。2. 手册的章节骨架先读这三块再谈写程序一本完整的 8086 数据手册通常由引脚描述、编程模型、指令集、总线时序、电气特性、封装等几大部分组成。电气特性那章是硬件工程师的封装那章是画 PCB 用的真正决定你能不能写出能跑的程序、能不能让板子正常复位是前面三块编程模型、指令集和时序。我讲一下每块该读什么、怎么读。2.1 编程模型章节寄存器与标志位才是程序的根编程模型章节会给出 8086 的寄存器全貌。这部分别扫一眼就过你需要把每个寄存器的隐含用途记牢。通用寄存器 AX、BX、CX、DX 各有约定AX 是累加器乘除法、输入输出指令默认走它BX 常作基址寄存器用于查表CX 在循环和移位指令里默认当计数器DX 在乘除法和外设地址里当高半部分。SI、DI 是变址寄存器串操作指令里源和目的默认是 DS:SI 和 ES:DI。SP 和 BP 都跟栈相关SP 指向栈顶BP 常用于访问栈里的参数和局部变量。四个段寄存器 CS、DS、SS、ES 是整个 8086 寻址的关键。手册里会说「物理地址 段寄存器 × 16 偏移量」这句话几乎所有讲 8086 的书都有但真正容易忽略的是段寄存器的值在复位后是确定的CS FFFFHIP 0000H所以第一条指令的物理地址是 FFFF0H。很多人在调试器里看到第一条指令在 FFFF0H 执行不明所以查一下复位时序段就明白了。FLAGS 寄存器里的标志位更要逐个确认。进位标志 CF、辅助进位 AF、零标志 ZF、符号标志 SF、溢出标志 OF 是算术逻辑最常用的五个方向标志 DF 影响串操作的方向中断允许标志 IF 决定可屏蔽中断是否响应。查手册时留意每个标志位是被哪条指令影响的比如 INC 指令不影响 CF而 ADD 会这段逻辑初看没问题写底层代码时全是要命的地方。建议把寄存器分组和默认用途做一张速查表贴在屏幕边上我就不贴了手册上那张寄存器图比任何转述都准确。2.2 指令集与寻址方式怎么从手册快速定位指令指令集这一章新手最常见的误区是从第一条开始背。手册不是教材它是字典。你需要的是「我要做某个操作查哪条指令」而不是「手册里有什么指令」。8086 指令的助记符不多但寻址方式组合非常多。一条 MOV 指令就有寄存器到寄存器、立即数到寄存器、内存到寄存器、寄存器到内存等好几种变体手册里通常以指令摘要表形式列出每个变体单独一行操作码、操作数、字节长度、执行周期数。我在实际读手册时会先锁定操作数类型再去指令表里找对应行。比如我要把一个立即数送入 DS 段寄存器直接写 MOV DS, 1234H 是不行的8086 的段寄存器不支持立即数直送。手册上会写清楚 MOV Sreg 的合法来源只能是通用寄存器或内存于是正确写法是先把立即数放入 AX再 MOV DS, AX。这种「非法组合」在手册的指令格式说明里都明明白白只是很多人不看格式一栏直接凭感觉编。指令表里每一行末尾的时钟周期数值得养成看的习惯。它代表这条指令在标准总线周期下消耗的时钟个数不是纳秒。比如 MOV reg, imm16 在 8086 上是 4 个时钟周期MUL 指令的周期数高达 70 到 119 个。用延时循环、做时间敏感的外设操作时这些数字直接影响延时是否准确。这个细节放到第 5 章讲耗时估算时再展开。2.3 时序章节总线周期、等待状态与外部复位时序章节是 8086 手册里最「硬」的部分也是硬件能不能跑起来的分水岭。8086 的地址和数据线是分时复用的ALE 信号把地址锁存到外部锁存器后面 T2 到 T4 状态数据线才用来传数据。手册里的读周期时序图标了每个状态何时放地址、何时读数据、数据有效后多少时间可以采样。这里多数人一开始想不明白的是等待状态到底怎么插入。手册会讲READY 引脚在 T3 状态前被采样如果 READY 为低总线就自动插入一个或多个 TW 等待状态直到 READY 变高。外部慢速设备或存储器就需要用这个机制来延长总线周期。我见过有开发者板子跑不起来连 READY 都没接悬空了事上电后十次有八次读写随机失败这就是没看时序章节的后果。复位时序也是容易被忽略的。手册要求 RESET 信号高电平至少保持 4 个时钟周期复位后寄存器进入固定状态。硬件上如果复位电路时长不够系统会出现「按复位键能启动、断电重开不行」的诡异现象。这类问题不查时序图基本无解示波器抓一下 RESET 引脚低于手册最低要求就得改复位电路的 RC 参数。3. 用手册搭最小系统引脚表、锁存器与第一段汇编读手册最终要落到两条线逻辑接线和指令编码。这一章从引脚描述表出发搭一个能跑起来的 8086 最小系统然后烧进去第一段可执行的汇编代码。3.1 从引脚描述表圈出必须接的引脚8086 是 40 脚封装数据线 D15-D0 和地址线 A19-A0 分时复用低 16 位地址在 T1 状态出现在 AD15-AD0 上靠 ALE 信号锁存。所以外部必须接至少两片 8 位锁存器常见方案是两片 74LS373把地址锁住否则数据线上地址和数据来回切换所有外设都无法稳定工作。硬件手册里这部分写得非常清楚每个引脚都有表格说明方向、功能和时序要求。我从引脚表里圈出来最重要的几组时钟 CLK8086 要求时钟占空比大约 33%不是任意方波都能用复位 RESET高电平有效至少保持 4 个时钟周期READY外部慢速设备通过它请求等待不用的设备要接上拉电阻防止悬空产生随机等待中断请求 INTR 和 NMI最小/最大模式选择 MN/MX接地进入最大模式配合总线控制器接高电平进入最小模式自己搭最小系统通常用最小模式省一堆总线控制芯片。地址译码是搭系统时最容易出问题的环节。A19-A0 共 20 根地址线片选信号如果用 74LS138 这类译码器就要把高几位地址接进去。常见错误是只拿 A15 做片选导致高 4 位地址没参与译码内存出现镜像把两段不同地址映射到同一个物理芯片上。这个问题我在第 4 章专门讲接线前建议先把译码真值表列出来确认每个片选区间没有重叠。3.2 用指令表写第一段可烧录的启动代码最小系统硬件搭好后需要烧一段固件。启动时 CSFFFFH、IP0000H如果用了 EPROM 映射到 FC000H-FFFFFH那么 FFFF0H 处的第一条指令必须是跳转指令跳到真正的初始化代码去。这个布局不是随意定的完全由复位后的 CS:IP 决定。下面这段代码是典型的上电初始化流程用简化写法表示假设汇编器按小内存模型生成; 复位后第一条指令所在位置由硬件决定通常是跳转到此处 start: mov ax, 0 ; 立即数送入 AX间接设置段寄存器 mov ds, ax ; DS 0数据段指向内存低端 mov ss, ax ; SS 0栈段指向内存低端 mov sp, 1000h ; 栈顶设在 1000h 处 mov ax, 1234h ; 测试写入 mov word ptr [0000h], ax loop_here: jmp loop_here ; 主循环暂时无事可做这段代码的逻辑说明8086 不允许立即数直接送段寄存器所以先把 0 放入 AX再 MOV DS, AX这是手册指令表里「段寄存器只能由通用寄存器或内存加载」这一规则的实际应用。SP 要显式初始化否则复位后栈指针的值不确定将来一压栈就把未知地址写坏。最后jmp loop_here死循环保证程序不跑飞。代码里的mov word ptr [0000h], ax是间接寻址方括号代表内存操作数。默认数据段是 DS所以操作数物理地址是 DS×160000h也就是 00000h。如果你改了 DS 的值这个地址就会跟着变。新手调试时发现写进的字节不在预期地址多半就是没算段基址。3.3 中断向量表初始化把手册里的表地址变成可运行代码中断向量表位于内存最低端从 00000h 到 003FFh共 1024 字节每 4 字节一个向量对应 256 个中断类型。向量里前两个字节是 IP偏移后两个字节是 CS段基址这个排列顺序在手册中断章节里有明确描述写错一个字程序就跳飞。给某中断类型安装处理函数要做的是把函数入口地址按「先 IP 后 CS」写入对应位置。下面是安装中断类型 40h 的示例中断向量地址等于类型号乘 4xor ax, ax ; AX 0 mov es, ax ; ES 0段寄存器指向向量表所在段 mov di, 40h * 4 ; 中断类型 40h 的向量地址 40h * 4 mov word ptr es:[di], offset handler ; 写入偏移 mov word ptr es:[di2], seg handler ; 写入段地址 ; 之后用 int 40h 指令即可触发 loop_here: jmp loop_here handler: ; 中断处理逻辑 iret ; 中断返回指令这里有两个容易错的点。第一个ES 必须显式设置为 0不能假设它复位后就是 0手册里复位后 ES 的值是 0000H 吗不是只有 CS 被置为 FFFFH其他段寄存器的复位值手册通常标为 0000H但为了可读性和保险显式初始化是通用习惯。第二个offset和seg是汇编器提供的运算符分别取符号的偏移和段地址如果你手工算地址反而容易错。安装完中断向量后可以用int 40h触发观察是否能正确进入 handler。这是验证向量表写没写对的最快方法。进入 handle 后要记得用 IRET 返回而不是 RETIRET 会从栈里恢复 IP、CS、FLAGS 三个值RET 只恢复 IP栈里状态错乱。4. 排查与避坑手册没说但系统一定会踩的 5 个坑手册把「正常情况」写得清清楚楚但实际系统跑起来出问题的永远是那些手册里只会一笔带过、甚至不带过的细节。这一章写我反复遇到的 5 个具体坑按现象、原因、解决的顺序说清楚。4.1 上电偶发复位程序跑到一半突然重启现象系统上电后大部分时候能工作但偶尔在读写外部存储器时重启或者在温度升高后故障率上升。用万用表量电压都正常换了电容也没用。原因复位信号和时钟的时序余量不足。手册规定 RESET 高电平保持时间至少 4 个时钟周期同时复位释放必须在时钟上升沿附近满足建立保持时间。如果复位电路用的是简单的 RC 充放电阻容值选得过临界温度变化就会让复位脉冲宽度掉到临界值以下。另外一个隐藏因素是电源上电斜率太慢导致 RESET 已经释放但时钟还没稳定。解决先拿示波器同时抓 CLK 和 RESET 两个通道测量 RESET 高电平宽度和手册要求对比。发现问题后用专门的复位监控芯片替代纯 RC 电路或者加大电容使复位脉冲宽度留有至少两倍余量。同时检查 CLK 芯片的电源滤波确保时钟在复位释放前已稳定至少十个周期。4.2 程序跳飞中断处理函数执行几次后整个系统死掉现象写好的中断处理程序单步执行第一次正常连续触发第二次就开始乱跳有时干脆卡死。原因中断向量表里只写了 IP没写 CS或者两个字节的写入顺序不对。中断向量表每个向量是 CS:IP 共 4 字节IP 在前低地址CS 在后高地址。如果只写偏移CS 保持复位后的默认值或残留值中断触发后 CPU 直接跳到一段不存在的代码。另一种常见情况是写向量时用了MOV [0000H], AX这类指令没显式指定段寄存器结果写到了 DS 指向的错位置。解决写中断向量前先确认 ES0再按「先偏移、后段址」的顺序写入两个 word。调试时在向量表区域设一个内存断点看触发中断后 CPU 到底从哪个物理地址取指令。正确的向量地址 中断类型号 × 4比如类型 40h 的向量地址是 100h这个换算别当成十进制直接乘。4.3 访问不同地址却选中同一片存储器现象往 80000h 写数据发现 00000h 的内容也跟着变了两段地址似乎映射到了同一块物理内存。原因地址译码只用了部分地址线比如只拿 A15 做片选高位地址 A19-A16 完全没有参与。这样 8086 的 20 位地址空间被压缩成 32KB 的重复镜像只要 A15 相同不管高位是什么值都会选中同一片芯片。手册里虽然讲了地址总线宽度是 20 位但译码逻辑怎么接需要你自己根据存储器容量推算。解决片选译码必须覆盖所有未参与片内寻址的高位地址。16 位地址线已经给 64KB 寻址的话A19-A16 这 4 根仍要参与译码才能确保每个存储区只在唯一地址区间出现。用 74LS138 时要把高 4 位按二进制组合接到使能端和选择端并列出完整真值表检查。4.4 程序在新批次芯片上行为不一致旧代码跑出新结果现象同一套固件A 批次的 8086 上运行正常B 批次上某些算术运算的结果和预期不符。原因程序里把未定义或保留的标志位当成了默认值。8086 的 FLAGS 寄存器里有一位标志位在部分文档版本里标为保留位读出来可能不定某些新批次可能把它用作别的用途。旧代码里如果有人直接对 FLAGS 整体执行 PUSHF 后做位测试就可能读到不确定的值导致分支走错。解决代码里只检查手册明确列出的标志位对未定义的位一律用掩码隔离。比如测试进位标志用JC/JNC指令而不是 PUSHF 后 AND 整字。读 FLAGS 时先用AND清掉保留位再判断目标位。这个习惯在移植到其他 x86 兼容芯片时尤其重要因为保留位的处理各家定义不一样。4.5 手册版本不同同一引脚的时序参数对不上现象按手册上的读周期数据设计的外设接口在别人手里的同型号芯片上就是偶尔丢数据。原因数据手册有多个修订版本早期版本的时序参数在后续批次里被更新过。引脚功能可能没变但建立时间、保持时间、输出延迟这些参数会有修正。只看初版手册或网上下载的扫描件没关注修订记录就按旧参数留了过小的余量。解决拿到芯片后先查对应批次的最新数据手册重点看封面角落的修订号和勘误页。设计时不要踩着手册参数的极限值最少留 20% 余量。如果条件允许用自己板子上实测的波形参数回填到设计文档比任何手册数值都可靠。5. 从纸面到验真用示波器与仿真器对照手册参数手册上的时序图画得再漂亮板子上的真实波形才是最终裁判。这一章讲怎么把手册里的参数变成调试工具里的测量项从硬件示波器到软件单步跟踪逐一排查。5.1 波形对照时序图三步定位硬件误判用示波器或逻辑分析仪对照手册读周期图总共三步。第一步抓关键控制信号把 CH1 接 CLKCH2 接 ALE将示波器触发设为 ALE 下降沿这样每次采样都能看到完整总线周期。第二步同时观察 RD 和地址/数据复用线。手册读周期图里ALE 下降沿之后地址必须保持有效一段时间RD 下降沿时数据线上应该出现有效数据。第三步对比手册标明的建立时间和保持时间用示波器的测量光标直接量两个边沿的间距。实测中最常见的问题是地址保持时间不足。因为 8086 的地址只在 T1 状态输出之后数据线开始切换方向外部锁存器如果建立时间偏长地址就有丢失风险。这时示波器上能看到 ALE 下降沿之后 AD 线上地址波形立刻开始畸变。解决方向是换用建立时间更短的锁存器或者降低时钟频率以满足手册最小时序要求。5.2 用单步跟踪验证寄存器与标志位硬件波形没问题后软件执行路径要靠仿真器或调试器单步跟踪验证。下面这段代码专门用于观察标志位变化你可以把它加载到调试器里单步执行对照手册里的标志位列表逐项核对mov ax, 0ffffh add ax, 1 ; 0ffffh 1 10000hCF1OF1AF1 mov bx, 0fffeh add bx, 2 ; 结果 10000hCF1ZF1 mov cx, 8000h add cx, 8000h ; 结果 0ZF1CF1OF1单步执行时重点观察三个位置第一条 ADD 之后 CF 和 OF 同时置位因为带符号数和无符号数都溢出了第二条 ADD 低 16 位结果是 0ZF 置一但 OF 不置一因为两个正数相加结果没有溢出到符号位第三条 ADD 两个负数相加结果符号位变成 0OF 置一。这些组合逻辑光看书容易混淆亲手跑一遍记忆最牢。调试器里还有一个容易被忽略的功能查看内存窗口时确认段地址。如果你设置了 DS0在调试器内存窗口输入 0000:0000 和输入 0000:1000 显示的是不同区域但如果段寄存器设错了看到的数据就完全不对。用手册的段基址公式自己心算几个地址能快速排除调试器显示误导。5.3 把手册里的「总线周期数」换算成程序耗时手册指令表里的周期数乘以时钟周期才是真正的指令执行时间。这个换算很多人忽略8086 的时钟频率是外部 CLK 决定的一个总线周期占 4 个时钟状态 T1-T4但每条指令的周期数单位是「时钟周期」而不是「总线周期」。比如 MOV reg, imm16 是 4 个时钟周期在 5MHz 时钟下每个时钟周期 200ns单条指令耗时 800ns。下面是一段延时循环的耗时粗算示例; 假设 CLK 5MHz一个时钟周期 200ns ; 指令周期数取自手册LOOP 17 个时钟周期循环跳转时 ; DEC 3 个时钟周期JNZ 16 个时钟周期跳转时 mov cx, 1000 ; 1 条 MOV耗时可忽略 delay_loop: nop ; NOP 3 个时钟周期 loop delay_loop ; LOOP 17 个时钟周期每次跳转NOP 加 LOOP 的组合每次迭代耗时为 (3 17) × 200ns 4μs1000 次迭代约 4ms。想精确调整延时就要根据手册调整循环体和计数器初值。手册里的周期数是理想值实际还要考虑内存速度、等待状态插入等所以工程上通常用示波器实测校准。6. 把手册变成自己的批注手册三个可以少走弯路的习惯手册是通用的但你的系统是特定的。我后来养成的习惯是把手册当成工作底稿直接在页边写自己的实测值和踩坑记录。第一个习惯是「参数实测回填」。手册上标注的建立时间、保持时间、复位脉冲宽度我都会在板子调通后用示波器量一遍把实测值写在对应参数旁边。第二次设计时直接参考实测值而不是手册极限值余量心里有底。第二个习惯是「为常用配置做一张汇总卡」。比如最小模式下的关键引脚接法、中断向量表地址换算、几个典型指令的周期数抄在一张 A4 纸上贴在调试台。手册翻起来慢调试时眼睛盯示波器哪有空一页页翻。这张卡不是抄手册而是抄你在这个项目里真正用到的子集换项目就重做。第三个习惯是「每次调不通先查勘误」。某次项目里 A 同学在系统里加了一个看似无害的延时函数结果中断响应变慢排查了两天最后发现那条延时指令的周期数在勘误页里被修正过旧手册给的数据偏小。从那以后我拿到新器件的第一件事就是找出最新版数据手册的勘误页扫描一遍再动手。这三条算不上技巧都是血泪换来的习惯。希望帮到你。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →