
简介《IBM-PC汇编语言程序设计》习题参考答案面向使用沈美明、温冬婵版教材的计算机专业学生与自学者用于课后练习对照与知识点查漏补缺。文档按章节收录习题解答覆盖数制转换、8位补码表示及加减运算、溢出与进位标志判定、位运算规则、ASCII码与字符串编码、存储器物理地址计算等核心内容并附有部分图解与详细计算过程。整份答案以单个doc文档打包共1个文件压缩包大小约524KB方便直接打开查阅或打印。当前已有114人学习浏览。通过逐题复盘读者可系统巩固汇编语言的数据表示与寻址方式提升阅读与编写底层程序所需的逻辑思维能力尤其适合备考、作业自查及考前集中复习场景。1. 为什么一本汇编习题答案值得从头读一遍从十进制到机器码的必修课很多人在学汇编时翻开课本第一页就被劝退了满页的二进制、十六进制、补码、标志位看起来像天书。但你可能没意识到汇编语言最折磨人的地方恰恰也是它最值钱的地方——它逼你把“数在机器里到底长什么样”这件事想明白。这本《IBM-PC 汇编语言程序设计》的习题答案其实就是把一个初学者最容易卡住的那些点一个一个拆开揉碎了给你看十进制怎么变成二进制和十六进制、负数在内存里用什么形式存在、CPU 算加法时凭什么知道结果对不对、内存地址怎么由段地址和偏移地址拼出来。这些问题如果你只是上课听讲很容易觉得“好像懂了”但一到做题就会露馅。而习题答案的价值就是让你有一份对照答案知道自己到底哪一步推错了、哪里理解歪了。一句话说透汇编习题答案不是用来背的它是你在“机器码世界观”里迷路时的导航地图。2. 数制转换为什么十六进制是汇编的“母语”2.1 进制不是数学题而是一种“分组习惯”你第一次做进制转换可能是在算 369 等于多少二进制。但如果只把它当成数学题就错过了最重要的东西。日常十进制里我们“逢十进一”二进制是“逢二进一”十六进制是“逢十六进一”。听起来很绕但打个比方就明白了你数鸡蛋既可以一个一个数二进制也可以两个两个数还是二进制还可以十六个装一盒、按盒数十六进制。盒子的存在不是为了难为你而是因为一盒刚好对应一种常见的东西——比如 CPU 里的 8 位、16 位寄存器。习题里反复出现的套路是(1) 369 1 0111 0001B 171H。拆开看先转二进制再把二进制从右往左每四位分一组每组对应一个十六进制位。为什么每四位一组因为四位二进制最大是 1111正好等于十六进制的 F不多不少。这就是十六进制存在的根本理由它是二进制的“压缩写法”一位十六进制等于四位二进制不用像十进制那样做复杂的乘除法才能换算。2.2 转换不是死算而是看“位权”很多人做转换慢是因为在硬算。比如把 32767 转二进制就不断除以 2、记余数一直除到 0。这种方法没错但效率低而且容易错。更聪明的做法是直接看“位权”二进制每一位代表 2 的 n 次方十六进制每一位代表 16 的 n 次方。32767 这个数很特殊它等于 2 的 15 次方减 1所以二进制是 15 个 1即 111 1111 1111 1111B转十六进制就是 7FFFH。习题答案里给的34095 FFFFH、432767 7FFFH其实全都在暗示这个规律当你知道一个数接近 2 的整数次幂时直接写二进制要比做除法快得多。这也是汇编实战里的血泪经验写程序时经常要算 mask掩码、算边界值能一眼看出“这个数是 2 的 n 次方减 1”的人写出来的代码比拿着计算器的人快一倍。2.3 反向转换十六进制回二进制考验的是“拆位”能力从十六进制转二进制是汇编里更常见的操作因为你在调试程序时看到的寄存器值往往都是十六进制比如 AX 4C2AH你要快速知道它的二进制长什么样。方法很简单把每一位十六进制数展开成四位二进制。4 是 0100C 是 11002 是 0010A 是 1010拼起来就是 0100 1100 0010 1010B。但这里有个初学者容易翻车的地方C 的二进制是 1100拆出来不足四位要在前面补 0 补足四位。很多人直接写 C 对应的二进制 1100结果后面拼起来位错位了整个数就废了。另一个练习是”拆位补位”题比如把 FAH 转二进制F 是 1111A 是 1010合起来是 1111 1010B对应十进制 250。这里的 250 就是 255 减 5是汇编里很常用的“上界数”。这类数字见多了你对二进制和十六进制的直觉就建立起来了不再需要每次去查表。3. 补码与标志位负数在计算机里的“分身术”3.1 减法为什么能变成加法补码的钟表模型习题 1.5 里有一组很“劝退”的题用 8 位二进制补码计算 (-85)76、85-(-76) 这类式子还要判断 CF 和 OF 标志。要理解这题先得回答一个更基础的问题为什么计算机不用“符号位加绝对值”这种直观表示负数偏要用补码打个比方钟表上 9 点可以理解为 12 点往前拨 3 小时也可以理解为往后拨 9 小时。在 12 小时的体系里-3 和 9 是同一个位置。计算机的补码就是这个道理8 位二进制有 256 个状态把 128 到 255 这些“看起来是正数”的二进制数重新解释成 -128 到 -1就得到了补码。补码最大的好处是减法可以统一成加法。85-76 在机器里不是直接做减法而是 85 加上 -76 的补码。习题答案里专门把 85-76 改写成了 85(-76) 的补码相加形式就是这个原因。CPU 里不需要单独造一套减法电路加法和减法共用一套加法器硬件更简单速度更快。这就是补码存在的全部意义用一套加法逻辑通吃正负数的加减运算。3.2 标志位不是“辅助信息”而是运算结果的“体检报告”习题 1.5 的答案在每个算式后面都跟了 CF0、OF1 这样的标志很多初学者直接忽略它们觉得“我算对结果不就行了”。但标志位恰恰是汇编里最核心的隐藏信息。CF进位标志记录的是无符号运算时最高位有没有向更高位进位或借位OF溢出标志记录的是带符号运算时结果有没有超出表示范围。两者看的都是“越界”但一个按无符号解释一个按带符号解释。举个例子85-(-76) 算出来是 0A1H如果把它看作无符号数0A1H 是 161没问题但如果你把它看作带符号数0A1H 的最高位是 1代表负数这就不对了。答案给出的 OF1 就是在说带符号视角来看这个结果溢出了。而 CF0 表示无符号视角没越界。同一段二进制两种身份两套标准这就是汇编初学者最懵的地方一个数到底该按无符号还是有符号看取决于你把它放进哪条指令里。3.3 从补码题里学到的“读寄存器”习惯这些补码习题还有一个隐藏收获培养读寄存器的习惯。每一道题的答案都写了“MOV AX, 1234H(AX)1234H”这类注释看似啰嗦其实是汇编调试的基本功。你在 DEBUG 里看寄存器看到的永远是十六进制比如 AX0F7H你得立刻反应过来这可能是 -9 的补码也可能是 247具体是哪个取决于程序把它当什么用。这种“一个值多个身份”的思维方式是汇编独有的。学过汇编再看 C 语言的 unsigned 和 signed你会觉得 C 真是体贴因为类型帮你把身份定死了。4. 寄存器与寻址方式CPU 的“工作台”和“取货方式”4.1 寄存器不是一排储物柜而是一张有分工的工作台习题 2.7 问“下列操作可以使用哪些寄存器”这种题看起来是在考记忆其实是在讲 CPU 的工作台面布局。你可以把寄存器想象成厨房里的操作台AX 是“主力炒锅”加减乘除都靠它CX 是“计数器”循环的时候专门用它数次数DX 是“辅助锅”乘法和除法结果太长时用来放多出来的部分BX 则比较特殊既能算数又能当“指针”指向内存地址。每个寄存器都有自己的脾气不是随便乱用的。习题 2.9 的连线题里有一组非常容易错的概念存储器和堆栈。存储器是一个大仓库数据按地址存放想取哪个取哪个堆栈则是一个叠盘子器只能从顶端放盘子、从顶端取盘子后放进去的先拿出来。这两个概念一混后面的 PUSH、POP、CALL、RET 全都会理解歪。习题 3.13 专门画了堆栈区示意图让你看到 SP 指针怎么随着 PUSH 和 POP 上下移动。答案里 (SP)00B0H先 PUSH 8057HSP 变成 00AEH再 PUSH 0F79HSP 变成 00ACH最后 POPSP 又回弹到 00AEH。这个过程不看图很难有直觉堆栈地址是往下长的越 PUSH 地址越小所以“栈顶”其实是地址最小的那个单元。这一点搞反了写栈操作代码必踩坑。4.2 寻址方式你的数据放在哪用哪种“物流方式”去取寻址方式是第三章的核心也是很多初学者的噩梦。它看起来像是一堆语法规则[BX]、[BX0B2H]、[BX][SI]、VAL[BX][SI]其实本质只有一句话CPU 要想办法找到一个操作数的地址不同写法代表不同“找法”。打个比方你在外卖 App 上填收货地址可以写“店里自取”立即数数据就在指令里可以写“我家柜子第三格”寄存器数据就在寄存器里可以写“幸福路 100 号”直接寻址地址直接写在指令里可以写“我朋友家钥匙在他邻居那”基址变址地址由寄存器组合算出来。习题 3.1 给了 (BX)637DH、(SI)2A9BH、位移量 D7237H让你算各种寻址方式的有效地址就是在模拟这类“找货”过程。其中最容易出错的是第 (7) 小题相对基址变址寻址算出来的 EA(BX)(SI)D1004FH但 16 位寄存器存不下这么长的地址最高位的进位 1 直接丢掉了最后 EA004FH。这个“进位丢失”很有教学意义它不是算错了而是 CPU 真的会这么做。所以当你看到汇编代码里的地址明显不对时先别怀疑代码写错很可能是溢出了。4.3 MOV 与 LEA一个是搬家一个是记门牌号习题 3.10 专门考了一组非常经典的对比MOV AX, TABLE 和 LEA AX, TABLE。前者把 TABLE 单元里的内容取出来发给 AX后者把 TABLE 单元的地址编号发给 AX。答案很清楚如果 TABLE 在 0032H 单元里面存着 1234H那么 MOV 之后 AX 是 1234HLEA 之后 AX 是 0032H。这两个指令的差别可以类比成MOV 是去朋友家把他家的电视机搬回来LEA 是只记下他家门牌号。很多新手写程序时习惯用 MOV AX, OFFSET TABLE 来取地址其实更地道的写法就是 LEA AX, TABLE。它们效果相同但 LEA 更直观而且在某些场景下还能“顺便做加法”比如 LEA AX, [BXSI2] 可以在取地址的同时完成一次地址计算一举两得。习题 3.11 就是这种综合题先 MOV BX, OFFSET TABLE再 ADD BX, ENTRY最后 MOV AX, [BX]这个三步连招在真实程序里非常常见本质就是数组按下标取元素。5. 最容易踩坑的 6 组易混概念看完不再懵这一章集中处理初学汇编时最容易混的几组概念。每一组都是“看着像其实根本不是一个东西”不掰开讲清楚后续写多少代码都会错。易混 1存储器地址 vs 存储器内容。这是新手的第一道坎。地址是门牌号内容是住在里面的人。MOV AX, [1200H] 是把 1200H 这个门牌号对应的房间里的人请出来而 MOV AX, 1200H 是把 1200H 这个数字本身当成数据。为什么容易混因为汇编指令里数字太多看着都差不多。怎么区分看有没有方括号。方括号就是“去这个地址取内容”的意思没方括号就是“这个数字本身”。易混 2物理地址 vs 逻辑地址。习题 2.4 是最经典的例子3017:000A、3015:002A、3010:007A 三段不同的“段偏移”组合算出来的物理地址竟然都是 3017AH。原因很简单段地址是左移四位再加偏移3017H 左移一位是 30170H加 0AH 得 3017AH3015H 左移是 30150H加 002AH 还是 3017AH。为什么容易混因为平时我们用的一维地址就一个数而实模式的内存地址要用两个数拼出来。怎么区分物理地址是 CPU 真正放到地址总线上的值逻辑地址是程序员写在代码里的“段偏移”表示法。同一个物理地址可以有好几种逻辑写法就像同一个房子可以说“幸福路 100 号”也可以说“幸福路 5 号院 2 栋 100 室”。易混 3CF 进位标志 vs OF 溢出标志。这两个标志都跟“数太大”有关但服务的对象完全不同CF 看的是无符号数有没有超过 0~2558 位或 0~6553516 位的范围OF 看的是带符号数有没有超过 -128~127 或 -32768~32767 的范围。为什么容易混因为一次运算可能两个标志同时变化而且有时候 CF1 的同时 OF0有时候反过来。怎么区分记住一个判断口诀如果最高位产生进位或借位就影响 CF如果两个加数符号相同而结果符号变了就影响 OF。易混 4带符号数 vs 无符号数。同一个二进制数两种解释两套结果。习题 1.6 里 D8H按无符号数是 216按带符号补码是 -40。为什么容易混因为 CPU 不区分它只管把二进制存起来怎么解释全看指令和程序员。怎么区分看后续指令如果接着做无符号比较JA、JB就当无符号如果做带符号比较JG、JL就当带符号。这是一切“看语境定身份”的源头。易混 5直接寻址 vs 立即寻址。MOV AX, [1200H] 和 MOV AX, 1200H差一个中括号意思天差地别。立即寻址是“把 1200H 这个常数塞进 AX”直接寻址是“去内存 1200H 这个地址上把内容读进 AX”。为什么容易混因为写起来只差括号。怎么区分马上看有没有括号没有括号的常数叫立即数有括号的是地址。易混 6字节顺序 vs 高位在前。习题 2.2 里存放 1EE5H 在 000B0H 单元答案是低字节 E5H 放在低地址 000B0H高字节 1EH 放在高地址 000B1H图里画得清清楚楚。这就是小端存储Intel 处理器的默认习惯。为什么容易混因为我们人类读十六进制时习惯从左往右看大端在前而小端存储是“低位在前”。怎么区分记一个场景当你用 DEBUG 的 d 命令看内存时看到 34H 12H对应的字是 1234H 而不是 3412H。只要这一条记住了调试时就不会把数据读反。6. 什么时候需要这份答案啃汇编的三个关键时刻这本《IBM-PC 汇编语言程序设计》的习题答案最有用的场景不是考试前突击而是三个具体的“认知关口”。第一个关口是“数制刚打通但还不敢做题”的时候。你刚学了进制转换和补码觉得道理都懂但一碰到 369 转二进制、85-(-76) 用补码算这种题手就开始抖。这时候集中做第一、二章的习题每做一题就对照一次答案重点不是看最终数对不对而是看你中间补的 0 够不够、补码转换的符号扩展有没有漏。我当年在这一阶段最大的毛病就是二进制转十六进制时补 0 不规范明明 101 1011B 是 5BH我当成 5B 少补了一位 0结果后面全错。对照答案能很快揪出这类系统性错误。第二个关口是“寻址方式学完觉得全都会做题全不对”的时候。第三章的寻址方式题是最值得反复做的因为它不是死记语法而是训练你在脑子里建立“寄存器内容 位移量 段默认规则 物理地址”的完整链路。习题 3.4 给了 (DS)2000H、(BX)0100H、(SI)0002H 和一大串内存数让你算七条指令执行后 AX 的值这种题做一遍顶看十遍概念。我第一次做的时候(5) MOV AX, 1100[BX] 和 (7) MOV AX, 1100[BX][SI] 被我完全搞混后来对照答案才发现一个是基址加位移一个是基址变址加位移差一个 SI 就完全是另一个地址了。第三个关口是“要写一个真正的小程序但不知道从哪下手”的时候。第三章后半部分有大量字符串操作的习题比如把字符串从右到左传送、查找字符串中的空格、把 ‘’ 替换成空格这些几乎是汇编实战里最常见的操作。习题 3.30 的答案里有一段 REPNE SCASB 之后用 DEC DI 修正指针的代码这就是无数人翻过车的经典坑REPNE SCASB 找到匹配字符后DI 会停在匹配位置的下一个单元必须 DEC 回去才能正确替换。答案里的注释把这个细节标得明明白白你看一遍记一辈子。从那以后我每次查一个汇编概念都强制自己走一遍“先做题、再对答案、最后总结经验”的流程而不是直接翻结论。这个过程能帮你把“看懂了”变成“真会了”。希望你也能用这份答案把汇编这座看起来吓人的山头一点一点翻过去。希望帮到你。本文还有配套的精品资源点击获取