news 2026/10/31 11:33:51

汇编语言程序设计答案:数制、补码、寻址方式与标志位详解

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
汇编语言程序设计答案:数制、补码、寻址方式与标志位详解

简介:《IBM-PC汇编语言程序设计答案》是一份面向汇编语言初学者与课程复习者的习题解答文档,对应沈美明、温冬婵编著的教材,帮助读者核对课后练习、梳理IBM-PC平台汇编语言的基础概念与解题思路。压缩包内共1个doc文件,大小约524KB,内容按章节和题号组织,便于检索对照。文档围绕数制转换、补码表示、位运算、ASCII码与字符串处理等知识点展开,包含十进制、二进制、十六进制互转,8位补码加减及CF、OF标志分析,AND、OR、NOT、XOR等位操作,以及字符编码与字符串ASCII值计算等典型题解。已有116人学习下载,适合课堂同步练习、考前查漏补缺,也可作为理解数据表示、运算规则和汇编基础逻辑的参考材料。

1. 做完题对不上答案的那种慌:汇编习题答案到底解的是什么

学汇编的人大多有过这种时刻:教材翻了三遍,例题也看懂了,一合上书做课后题,算出来的十六进制数跟标准答案差一位,然后就卡在那里,不知道是自己算错了还是理解错了。这份汇编语言程序设计答案,解的就是这个卡点——它把早期 16 位 PC 平台上那门汇编课每一章的习题,从数制转换、补码运算、寻址方式计算,到标志位判断、指令序列编写、字符串处理,一条条写出完整过程,而不是只甩一个结果。汇编这门课的特别之处在于它离硬件太近,中间任何一步取反、进位、段基址加错,后面的结果就全歪,所以只给结果的答案几乎没有参考价值,能对着核对的必须是过程。搞懂这份资料里反复出现的那几类计算,你手上的汇编就不再是靠背的东西。

2. 为什么汇编的作业最容易翻车:机器里那套数字规则

汇编课的第一道坎不是指令,是数字。同一串二进制位,放在不同语境里意义完全不同,而课本往往默认你已经懂了这些约定。这份答案的第一章几乎全是这一类题:十进制转二进制、二进制转十六进制、补码运算、ASCII 对照。看起来像小学算术,实际上是在训练一种「换视角」的习惯——先问这个数按什么规则解释,再动手算。

2.1 十进制、二进制、十六进制:其实只是「几个一盒」

换个说法会好懂很多:进制就是打包的规格。十进制是十个一盒,二进制是两个一盒,十六进制是十六个一盒。把十进制数转成二进制,就是不断按「两个一盒」去分,分到不能再分为止,余数从后往前读;转十六进制同理,只是把盒子从两个换成十六个。

拿答案里的 369 举例。它拆成二进制是 1 0111 0001B,拆成十六进制是 171H。手算的过程是:369 除以 2 得 184 余 1,184 除以 2 得 92 余 0,一路除下去把余数倒着排;而算十六进制时直接除 16 更快,369 = 16×23 + 1,23 = 16×1 + 7,所以是 171H。答案里那几个特殊值值得单独记一下:4095 是 FFFH,因为它正好是 2¹²−1;32767 是 7FFFH,是 16 位能装下的最大正数;65535 是 FFFFH。凡是看到一串全是 F 的十六进制数,基本就是 2ⁿ−1,这个直觉能省掉不少计算。

二进制和十六进制之间的换算是另一条捷径:四位二进制正好对应一位十六进制,从右往左四位一组切开就行。1000 0000B 切成 1000 和 0000,就是 80H,也就是 128;1111 1111 1111 1111B 切成四组全是 1111,就是 FFFFH。反过来,一位十六进制拆成四位二进制,FAH 拆成 1111 和 1010。

# 用代码核对答案里的三组转换,省得手算出错 nums = [369, 10000, 4095, 32767] for n in nums: # bin() 输出带 0b 前缀,hex() 输出带 0x 前缀 print(n, bin(n)[2:].upper() + "B", hex(n)[2:].upper() + "H")

这段代码做的事情就是把手算结果验一遍,[2:]是切掉 Python 自动加的前缀,upper()把字母转成大写,跟教材里FFFH这种写法对齐。参数只有nums这一处需要改,换成你自己作业里的数就能对照。手算和代码各走一遍,你会发现错的地方往往不是除法,而是某一位余数抄漏了——这正是答案里把每一步中间结果都写出来的意义。

十六进制的四则运算也一样,答案里 3A+B7=F1H、1234+AF=12E3H、ABCD−FE=AACFH 这几题,都要再用十进制校核一遍(F1H=241、12E3H=4835、AACFH=43727)。校核不是多余步骤,它是唯一能拦住「十六进制算对了但十进制换算错了」这类错误的关卡。

2.2 补码:为什么负数要长成那副奇怪的样子

很多人第一次看到 −85 在 8 位里写成 1010 1011B,第一反应是「符号位加绝对值不就行了」。答案里所有补码题都在反复说明一件事:机器只会做加法,它没有减法电路。

打个比方,钟表上现在是 3 点,你想把它拨回 12 点,可以倒拨 3 格,也可以正拨 9 格。12 小时制的表盘上,「减 3」和「加 9」是同一件事。补码干的就是这个:把一个负数换成一个足够大的正数,让减法变成加法,加完之后自然溢出丢掉的部分刚好抵消。8 位二进制的表盘大小是 256,所以 −85 等价于 256−85=171,也就是 1010 1011B。

求法在答案里体现得很统一:取反加一。85 是 0101 0101B,逐位取反得到 1010 1010B,再加 1 就是 1010 1011B,即 0ABH。反过来,看到 0ABH 想知道它是多少,同样取反加一回去,得 85,所以它是 −85。8 位补码能表示的范围是 −128 到 127,这个范围要背下来,它是判断溢出的前提。

答案里 1.5 那一组题,是整份资料里最能说明问题的地方。85+(−76) 的结果是 09H,但答案同时标了 CF=1、OF=0。很多人在这里卡住:既然进位了,为什么不算溢出?因为 CF 和 OF 管的是两件不同的事。CF 看的是无符号数这一侧:0101 0101 加 1011 0100,最高位确实往外套了一个 1,所以 CF=1。OF 看的是有符号数这一侧:一个正数加一个负数,结果不可能跑出范围,所以 OF=0。两个标志同时「一个是 1、一个是 0」,完全合理。

再看 85−(−76)=0A1H,CF=0、OF=1。这次没有无符号进位,但 85+76=161 超过了 127,有符号数装不下,于是 OF=1。同一道题的两个标志给出了相反的信号,这就是为什么答案要把 CF、OF 分开列,而不是笼统写「溢出」。

1.6 那道题更直白:D8H 当成无符号数是 216,当成补码是 −40。FFH 当成无符号是 255,当成补码是 −1。一个字节没变,解释规则变了,值就变了。这不是文字游戏,是汇编里天天要面对的现实——你写指令时用MUL还是IMUL,决定了 CPU 按哪套规则理解同一串位。

2.3 一个字节的三种身份:数字、字符、机器码

答案第一章最后几题在讲 ASCII:4FH 是十进制 79,也是字符 O;2BH 是 43,也是加号;73H 是 115,也是小写 s;59H 是 89,也是大写 Y。

这里面有个很实用的小规律,答案里没明说但做题时能感觉到:数字字符 0 到 9 的编码是 30H 到 39H,大写字母 A 到 Z 是 41H 到 5AH,小写字母 a 到 z 是 61H 到 7AH。大小写同一字母之间只差 20H,比如 A 是 41H、a 是 61H,只差最高位的那个 1。所以要把大写转小写,加 20H 或者对某一位做个 OR 就够了,这类技巧在后面位运算的题里会再出现。

答案里那道写字符串 ASCII 码的题,把For example,逐字符展开成 46H 6FH 72H 20H……,末尾还跟了 0AH 0DH。这两个是换行和回车,教材里习惯这么写。它提醒的其实是:字符串在内存里就是一串连续的字节,没有「字符串」这个东西,只有字节和你脑子里的解释。

到这里可以串起来了:同一个字节 4FH,可以是数字 79、字符 O,也可能是某条指令机器码中的一个字节。汇编和高级语言最大的差别就在这——高级语言里类型是变量自带的,汇编里类型是你自己心里记着的。答案里那些看似重复的换算题,训练的就是这份「心里有数」。

3. 答案里反复出现的那类题:地址与寻址方式

翻开这份资料的第二、三章,题目风格会变:不再是纯数字换算,而是一堆(DS)=2000H、(BX)=0100H、(20100H)=12H这样的条件。这类题在考什么?考的是「CPU 怎么找到那个数据」。理解了这一层,后面写指令序列才不会瞎猜。

3.1 段地址加偏移:两串不同的数字指向同一扇门

早期 16 位机的地址总线是 20 位,能寻址 1MB 空间,但寄存器只有 16 位,最大只能表示 65535。用 16 位的寄存器去表示 20 位的地址,中间差着 4 位,解决办法就是分段:地址拆成「段基址」和「偏移量」两部分,实际地址按「段基址 ×16 + 偏移量」算出来。

这个规矩可以类比成写地址:同一个地方,你可以说「某小区 3 号楼 502」,也可以说「某小区东区 5 单元 02 室」,说法不同,指的是同一户。答案里 2.4 那道题就是这个意思:3017:000A、3015:002A、3010:007A 三组写法,算出来全是 3017AH。3017H 乘 16(也就是左移一位十六进制)得 30170H,加 000AH 得 3017AH;3015H 乘 16 得 30150H,加 002AH 得 3017AH;3010H 乘 16 得 30100H,加 007AH 同样得 3017AH。

2.5 题是同一个公式的应用:CS=0A7F0H、IP=2B40H,程序第一条指令的物理地址是 0A7F0H×10H+2B40H=0AAA40H。注意这里乘的是 10H 而不是 16,两者是一回事,只是十六进制写法更顺手。

分段带来的另一个结果是「每个段最多 64KB」,因为偏移量只有 16 位。答案里 2.6 题让你根据 DEBUG 显示的寄存器值画存储器分段示意图,DS、ES、SS、CS 分别是四个段的起点,段与段之间可以重叠、可以相邻,也可以隔开老远,没有强制要求。

还有一个容易被忽略的细节:字在内存里是「低字节放低地址」。答案里 30021H 字单元的内容是 AB34H,而 30022H 字节单元是 ABH、30021H 字节单元是 34H——把 34H 放在前面、ABH 放在后面,这个顺序叫小端。理解这一点,看内存图示才不至于看反。

3.2 七种寻址方式:有效地址 EA 是怎么凑出来的

寻址方式这个词听着唬人,说白了就是「操作数的地址怎么算出来」。答案里 3.1 那道题把七种方式一次性摆了出来,条件是 (BX)=637DH、(SI)=2A9BH、位移量 D=7237H。

寻址方式典型写法EA 怎么来答案里的结果
立即寻址MOV AX, 1200H没有 EA,操作数就在指令里无
直接寻址MOV AX, [7237H]EA 就是位移量本身7237H
寄存器寻址MOV AX, BX没有 EA,操作数在寄存器里无
寄存器间接MOV AX, [BX]EA = (BX)637DH
寄存器相对ADD [BX+0B2H], CXEA = (BX) + D0D5B4H
基址变址ADD AL, [BX][SI]EA = (BX) + (SI)8E18H
相对基址变址MOV AX, 1100[BX][SI]EA = (BX) + (SI) + D1004FH,截断为 004FH

前两种最容易混:立即寻址的操作数是「值」,直接寻址的操作数是「地址处的值」。写法上区别就在方括号,MOV AX, 1200H是让 AX 等于 1200H,MOV AX, [1200H]是去 1200H 那个单元把内容取出来。答案里 3.10 题专门考了这个区别:MOV AX, TABLE取的是 TABLE 单元里存的内容 1234H,LEA AX, TABLE取的是 TABLE 自己的偏移地址 0032H。

表格最后一行那个 004FH 值得多说一句。637DH + 2A9BH + 7237H 手算下来是 1004FH,已经超过 16 位了。偏移量寄存器只有 16 位,最高位那个 1 直接被丢掉,剩下 004FH。这不是溢出错误,是设计如此——地址计算在段内回绕。很多人在这种题上纠结半天,其实只要记住「偏移量按 16 位算,超出的进位不管」。

还有一条隐含规则:默认用哪个段寄存器,取决于你在用什么基址寄存器。用 BX、SI、DI 做间接寻址,默认走 DS;用 BP,默认走 SS(堆栈段);串操作里的 DI,默认走 ES。答案里 3.8 题让你指出十二种写法的寻址方式和物理地址,考的就是这条:MOV AX, [BP]的物理地址是 SS×16+BP,而不是 DS。

3.3 标志位全家桶:CF 和 OF 根本不是一回事

答案里出现频率最高的六个字母大概是 CF、OF、SF、ZF。它们各管一摊,混淆了就会得出错误结论。

ZF 最简单:运算结果是 0,它就置 1。SF 看结果的最高位,是 1 就说明按有符号数看是负数。CF 是无符号数这一侧的进位或借位——加法时最高位往外套了一个 1,或者减法时不够减需要借,CF 就置 1。OF 是有符号数这一侧的溢出——两个同号数相加得到异号结果,或者异号数相减跑出范围,OF 就置 1。

答案里 3.15 和 3.16 两组题就是拿来练这个的。62A0H 加 1234H 得 74D4H,SF=0、ZF=0、CF=0、OF=0,一切正常。62A0H 加 9D60H 得 0000H,同时 ZF=1 和 CF=1:结果为零,且最高位确实往外进了一位。再看 1234H 减 4AE0H 得 C754H,CF=1,因为小减大不够减,得借位;但 OF=0,因为一个正数减一个正数,不可能发生有符号溢出。

DEBUG 里那一串NV UP DI PL NZ NA PO NC就是这些标志的缩写,每个字母代表一个标志的当前状态。答案里 2.6 题给出了这串显示,让你判断 OF、SF、ZF、CF 的值,其中 NZ 表示非零(ZF=0)、PL 表示正(SF=0)、NC 表示无进位(CF=0)、NV 表示无溢出(OF=0)。

提示:判断标志位时先问一句「这道题是按有符号算还是按无符号算」,答案往往两种视角都要给出,别只算一半。

4. 常见误区与易混概念:这几组概念最容易搞混

做到这里,概念大体成形了,但答案里那些出错率最高的地方,恰恰是几组长得很像的东西。下面这几组,是初学时最容易混的。

4.1 有效地址 EA 和物理地址 PA

易混点:算出一个地址,不知道要不要再加段基址。

为什么混:两个词都叫「地址」,符号还都带个 A。

怎么区分:EA 是段内的偏移量,是个 16 位的「门牌号」;PA 是加上段基址之后真正的 20 位地址,是「坐标」。答案里 3.1 题只问 EA,所以算出 8E18H 就够了;3.8 题问物理地址,就得再补上 DS×16。判断方法很简单:题目给的段寄存器值用上了没有,用了就是 PA,没用就是 EA。

4.2 MOV AX, TABLE 和 LEA AX, TABLE

易混点:两条指令看起来都在「取 TABLE」,结果一个得 1234H,一个得 0032H。

为什么混:汇编里不带方括号的符号名,天然有两种理解——它是那个单元,还是那个单元里的东西。

怎么区分:MOV是搬运内容,方括号省略时,汇编器把符号名当成内存地址去取内容;LEA的全称是 load effective address,它只算地址,绝不访问内存。所以一个拿到的是值,一个拿到的是位置。判断口诀:要看「里面装了什么」用 MOV,要拿「它在哪儿」用 LEA。

4.3 同一个 D8H,到底是有符号还是无符号

易混点:算出 D8H 是 216,答案却写 −40。

为什么混:字节本身不带符号,符号是你附加的解释。

怎么区分:看指令。MUL、DIV、JA、JB这一套按无符号理解;IMUL、IDIV、JG、JL这一套按有符号理解。看到 D8H,最高位是 1,按补码读就是负数,按无符号读就是 216,两个答案都对,取决于题目问的是哪一侧。

4.4 算术右移和逻辑右移

易混点:SHR和SAR都是右移,结果却不一样。

为什么混:名字只差一个字母,功能描述都叫「右移一位」。

怎么区分:SHR空出来的高位补 0,是做无符号除法;SAR空出来的高位补符号位,是做有符号除法,负数右移之后还是负数。答案里把 +53 和 −49 分别乘 2 除 2 的那道题就在演示这个:−49 用SAR右移一位得 0E7H,也就是 −25,保留了符号;如果误用SHR,就会变成一个很大的正数。左移这边SHL和SAL效果相同,都是低位补 0。

4.5 指令和伪指令:谁真正进了机器

易混点:DW、DB、EQU这些写法看起来跟MOV、ADD一样,都是「指令」。

为什么混:它们在源程序里长得一模一样,都占一行。

怎么区分:真指令在程序运行时由 CPU 执行,会被翻译成机器码;伪指令是给汇编器看的,只在汇编阶段起作用,不产生任何机器码。DW 23, 36, 2是告诉汇编器「在这儿留几个字,填上这些值」,程序跑起来时这一行早就消失了。答案里 3.9 题围绕ARRAY DW ...展开,考的就是你分不分得清「定义数据」和「操作数据」。

5. 什么时候该翻这份答案,什么时候该合上

这份资料最合适的用法,是当「对照表」而不是「抄写本」。下面这几种场景,翻它收益很高:一是手算完一道数制转换或补码题,想确认中间某一步有没有抄错;二是寻址方式算出的 EA 跟答案对不上,需要看它每一段是怎么加的;三是写完一段指令序列,不确定用MOV还是LEA、用SAR还是SHR;四是标志位判断拿不准,想看标准答案对 CF 和 OF 是怎么分开下的结论。

反过来,有两种时候最好合上它。第一种是题目还没动笔就想看解法——汇编的题感全在动手那几分钟里,看一眼答案,那几分钟就永远练不出来了。第二种是把答案里的指令序列整段背下来当模板,比如双字求绝对值那段NEG DX / NEG AX / SBB DX, 0,背下来当然能过作业,但换成三字长或者换成求补码,就完全不会了。

举个具体例子。答案里有一道题要求把 DX:AX 组成的双字整体左移 4 位,标准解法是分段处理:

MOV CL, 4 ; 移位数,先放进 CL,移位指令只认 CL 或立即数 SHR DX, CL ; 高字先右移,空出的低位稍后由低字补上 MOV BL, AH ; 先把低字的高 4 位暂存,右移会把它挤掉 SHL AX, CL ; 低字左移 4 位,低位补 0 SHR BL, CL ; 暂存的高 4 位右移到低位 OR DL, BL ; 拼回高字的低 4 位

这段代码的关键不在指令本身,而在MOV BL, AH那一行——如果没有它,SHL AX, CL会把低字最高处的 4 位挤出去,拼接就断了。参数上,CL必须放移位数,这是硬件规定;BL只是个临时中转,换成其他空闲寄存器也行,但不能用 DX、AX 里的字节。看答案的时候,真正要看的是「为什么先存这一手」,而不是把六行代码抄进作业本。

我的习惯是:每道题先自己算完,把结果写在纸上,再翻答案核对,对不上就把自己的过程逐步比对,找到第一个分叉点为止。有一年我图省事跳过这一步,直接把答案里的寻址方式结论背了下来,结果考试遇到一道 BP 参与的题,条件反射按 DS 算了物理地址,整道题的分全丢了——从那以后我每次碰到带 BP、SI 的地址计算,都强制走一遍「默认段是谁、EA 是多少、PA 再加什么」这三步。这份答案放在下载区,按章节对着做题就行,别当小说读。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/31 11:33:13

Context Graph技术:构建企业级AI理解的动态知识网络

1. Context Graph:企业级AI理解的基石 当ChatGPT等通用AI展现出惊人对话能力时,企业管理者们却发现:这些AI在理解企业专属业务流程时,常常表现得像"职场新人"。根本原因在于,通用AI缺乏对企业特有数据关系和…

作者头像 李华
网站建设 2026/10/31 11:32:34

自然语言驱动的数据分析与可视化技术解析

1. 项目概述:自然语言驱动的数据分析与可视化 在数据驱动的时代,数据分析能力已成为各行业的核心竞争力。然而传统的数据分析流程存在两大痛点:技术门槛高(需要掌握SQL等查询语言)和结果呈现不直观(需要额外…

作者头像 李华
网站建设 2026/10/31 11:31:44

OA数据字典设计解析:EXT_ATTR宽表、多态引用与考勤预聚合

简介:《致远OA V8.1 数据字典》是一份面向致远OA开发、实施、运维及二次开发人员的数据库结构速查文档,覆盖表结构、字段类型、约束条件与注释说明,主要用于解决表字段含义不清、SQL编写缺少依据、系统升级排查困难等问题。压缩包共1个PDF文件…

作者头像 李华
网站建设 2026/10/31 11:30:05

HTML前端开发系统训练指南:从基础到项目实战

1. 训练流程概述 在Web开发领域,HTML(超文本标记语言)作为构建网页的基础,其训练流程是每位前端开发者必须掌握的核心技能。一个完整的HTML训练流程不仅包括基础语法的学习,更涵盖了从页面结构设计到实际项目应用的完整…

作者头像 李华
网站建设 2026/10/31 11:29:56

C语言数据结构实验源码合集:从顺序表到图算法可编译工程

简介:这份南邮数据结构实验源码包面向正在学习数据结构课程的高校学生和需要复现实验的编程初学者,覆盖线性表、栈与队列、二叉树及哈夫曼树、图的基本操作与最短路径等典型实验主题,可用于对照课程进度理解存储结构与算法实现。压缩包共收录…

作者头像 李华
网站建设 2026/10/31 11:28:26

自动驾驶决策系统实战:基于Carla与深度强化学习

1. 项目概述:自动驾驶决策与深度强化学习的实战结合 自动驾驶技术近年来已经从实验室走向商业化落地,而决策系统作为自动驾驶的"大脑",直接决定了车辆在复杂交通环境中的表现。传统基于规则的决策系统在面对长尾场景时往往捉襟见肘…

作者头像 李华