此仓库中代码为我学习汇编过程中解决过的习题,如果你有其它相关练习打算分享,欢迎提 PR 补充。 你可以将你的解法分享到此仓库中,如果你有此意愿,请 fork 后在
code目录下新建一个以你名称命名的文件夹,将你的解法放置在该文件夹下并提交 PR。如果需要许可声明,请在你的目录下自行添加。
- 北京邮电大学,计算机学院,杨旭东老师《微机原理与接口技术》课程习题
- Windows 7 及以上版本:建议使用
DOSBOX,当前最新版本0.74。需下载masm.exe,link.exe,debug.exe。也可以选择emu8086,但该软件使用的汇编语言标准与 MASM 有差异。DOSBOX及配套的工具可以从此处下载。安装DOSBOX后运行安装目录下的DOSBox 0.74 Options.bat,在打开的dosbox-0.74.conf文件最后加上以下两句。其中path_to_your_tool需替换为你的masm.exe等工具所在的目录。要运行代码,请将代码复制到path_to_your_tool目录下,之后启动DOSBOX,在DOSBOX环境下编译、调试。
MOUNT C path_to_your_tool
set PATH=$PATH$;path_to_your_tool
- Linux/Mac:请访问
DOSBOX官网的 Download 界面,寻找自己系统对应的版本安装。 - 编译、链接,以
test.asm为例。
masm test.asm
link test.obj
建议:在解决问题本身的前提下,应尽量使程序有更好的容错性,能够尽可能处理非常规输入等可能引发异常的情况;应尽量使程序更好地面向用户,优化交互界面。
- 1、在
ARRAY数组中依次存储了七个字数据,紧接着是名为ZERO的字单元,表示如下:
(1) 如果 BX 包含数组ARRAY的初始地址,请编写指令将数据 0 传送给ZERO单元。
(2) 如果 BX 包含数据 0 在数组中的位移量,请编写指令将数据 0 传送给ZERO单元。
ARRAY DW 23, 36, 2, 100, 32000, 54, 0
ZERO DW ?-
2、请设置一个数据段
DATASG,其中定义以下字符变量或数据变量。
(1)FLD1B为字符串变量:personal computer;
(2)FLD2B为十进制数字节变量:32;
(3)FLD3B为十六进制数字节变量:20;
(4)FLD4B为二进制数字节变量:01011001;
(5)FLD5B为数字的ASCII字符字节变量:32654;
(6)FLD6B为10个零的字节变量;
(7)FLD7B为零件名(ASCII码)及其数量(十进制数)的表格:
PART1 20
PART2 50
PART3 14
(8)FLD1W为十六进制数字变量:FFF0;
(9)FLD2W为二进制数的字变量:01011001;
(10)FLD3W为 (7) 零件表的地址变量;
(11)FLD4W为包括5个十进制数的字变量:5, 6, 7, 8, 9;
(12)FLD5W为5个零的字变量;
(13)FLD6W为本段中字数据变量和字节数据变量之间的地址差。 -
3、假设程序中的数据定义如下:
PARTNO DW ?
PNAME DB 16 DUP (?)
COUNT DD ?
PLENTH EQU $-PARTNO
请问PLENTH的值为多少?它表示什么意义? -
4、有符号定义语句如下,问 L 的值是多少?
BUFF DB 1, 2, 3, ‘123’
EBUFF DB 0
L EQU EBUFF - BUFF- 5、假设程序中的数据定义如下:
(1) 用一条MOV指令将LNAME的偏移地址放入 AX 。
(2) 用一条指令将CODE_LIST的头两个字节的内容放入 SI 。
(3) 用一条伪操作使CODE_LENGTH的值等于CODE_LIST域的实际长度。
LNAME DB 30 DUP (?)
ADDRESS DB 30 DUP (?)
CITY DB 15 DUP (?)
CODE_LIST DB 1, 7, 8, 3, 2-
6、试写出一个完整的数据段
DATA_SEG,它把整数 5 赋予一个字节,并把整数 -1,0,2,5 和 4 放在 10 字数组DATA_LIST的头 5 个单元中。然后,写出完整的代码段,其功能为:
把DATA_LIST中头5个数中的最大值和最小值分别存入MAX和MIN单元中。 -
7、按下面的要求写出程序的框架
(1) 数据段的位置从0E000H开始,数据段中定义一个 100 字节的数组,其类型属性既是字又是字节;
(2) 堆栈段从小段开始,段组名为STACK;
(3) 代码段中指定段寄存器,指定主程序从1000H开始,给有关段寄存器赋值;
(4) 程序结束。 -
8、写一个完整的程序放在代码段
C_SEG中,要求把数据段D_SEG中的AUGEND和附加段E_SEG中的ADDEND相加,并把结果存放在D_SEG段中的SUM中。其中AUGEND、ADDEND和SUM均为双精度数,AUGEND赋值为 99251 ,ADDEND赋值为 -15962。 -
9、试编写一个汇编语言程序,要求对键盘输入的小写字母用大写字母显示出来。
-
10、编写程序,从键盘接收一个小写字母,然后找出它的前导字符和后续字符,再按顺序显示这三个字符。
-
11、将 AX 寄存器中的 16 位数分成 4 组,每组 4 位,然后把这四组数分别放在 AL、 BL、 CL和 DL 中。
-
12、试编写一程序,要求比较两个字符串
STRING1和STRING2所含字符是否完全相同,若相同则显示MATCH,若不相同则显示NO MATCH。 -
13、试编写一程序,要求能从键盘接收一个个位数 N ,然后响铃 N 次(响铃的 ASCII 码为
07H)。 -
14、编写程序,将一个包含有 20 个数据的数组 M 分成两个数组:正数数组 P 和负数数组 N ,并分别把这两个数组中数据的个数显示出来。
-
15、试编写一个汇编语言程序,求出首地址为
DATA的100D字数组中的最小偶数,并把它存放在 AX 中。 -
16、把 AX 中存放的 16 位二进制数 K 看作是 8 个二进制的 “四分之一字节”。试编写程序,数一下值为 3 (即 11B)的四分之一字节数,并将该数(即 11B 的个数)在终端上显示出来。
-
17、试编写一个汇编语言程序,要求从键盘接收一个四位的 16 进制数,并在终端上显示与它等值的二进制数。
-
18、设有一段英文,其字符变量名为
ENG,并以$字符结束。试编写一程序,查对单词SUN在该文中的出现次数,并以格式SUN:xxxx显示出次数。 -
19、从键盘输入一系列以
$为结束符的字符串,然后对其中的非数字字符计数,并显示出计数结果。 -
20、有一个首地址为
MEM的 100D 字数组,试编制程序删除数组中所有为 0 的项,并将后续项向前压缩,最后将数组的剩余部分补上 0 。 -
21、在
STRING到STRING+99单元中存放着一个字符串,试编制一个程序测试该字符串中是否存在数字,如有则把 CL 的第 5 位置 1 ,否则将该位置0。 -
22、在首地址为
TABLE的数组中按递增次序存放着 100H 个 16 位补码数,试编写一个程序把出现次数最多的数及其出现次数分别存放于 AX 和 CX 中。 -
23、数据段中已定义了一个有 n 个字数据的数组 M ,试编写一程序求出 M 中绝对值最大的数,把它放在数据段的
M+2n单元中,并将该数的偏移地址存放在M+2(n+1)单元中。 -
24、在首地址为
DATA的字数组中存放着 100H 个 16 位补码数,试编写一个程序求出它们的平均值放在 AX 寄存器中;并求出数组中有多少个数小于此平均值,将结果放在 BX 寄存器中。 -
25、试编制一个程序把 AX 中的 16 进制数转换为 ASCII 码,并将对应的 ASCII 码依次存放到
MEM数组中的四个字节中。例如,当(AX)=2A49H时,程序执行完后,MEM中的4个字节内容为39H,34H,41H,32H。 -
26、把 0~100D 之间的 30 个数存入以
GRADE为首地址的 30 字数组中,GRADE+i表示学号为i+1的学生的成绩。另一个数组RANK为 30 个学生的名次表,其中RANK+i的内容是学号为i+1的学生的名次。编写一程序,根据GRADE中的学生成绩,将学生名次填入RANK数组中。(提示:一个学生的名次等于成绩高于这个学生的人数加1。) -
27、已知数组 A 包含 15 个互不相等的整数,数组 B 包含 20 个互不相等的整数。试编制一程序把既在 A 中又在 B 中出现的整数存放于数组 C 中。
-
28、设在 A、B 和 C 单元中分别存放着三个数。若三个数都不是 0,则求出三数之和存放在 D 单元中;若其中有一个数为 0,则把其它两单元也清 0。请编写此程序。
-
29、试编写一程序,要求比较数组
ARRAY中的三个 16 位补码数,并根据比较结果在终端上显示如下信息:
(1) 如果三个数都不相等则显示0;
(2) 如果三个数有二个数相等则显示1;
(3) 如果三个数都相等则显示2。 -
30、从键盘输入一系列字符(以回车符结束),并按字母、数字、及其它字符分类计数,最后显示出这三类的计数结果。
-
31、已定义了两个整数变量 A 和 B ,试编写程序完成下列功能:
(1) 若两个数中有一个是奇数,则将奇数存入A中,偶数存入B中;
(2) 若两个数中均为奇数,则将两数加1后存回原变量;
(3) 若两个数中均为偶数,则两个变量均不改变。 -
32、假设已编制好 5 个歌曲程序,它们的段地址和偏移地址存放在数据段的跳跃表
SINGLIST中。试编制一程序,根据从键盘输入的歌曲编号 1~5,转去执行五个歌曲程序中的某一个。 -
33、下面的程序段有错吗?若有,请指出错误。
CRAY PROC
PUSH AX
ADD AX, BX
RET
ENDP CRAY-
34、写一段子程序
SKIPLINES,完成输出空行的功能。空出的行数在 AX 寄存器中。 -
35、设有 10 个学生的成绩分别是 76,69,84,90,73,88,99,63,100 和 80 分。试编制一个子程序统计 60
69 分,7079 分,8089 分,9099 分和 100 分的人数,分别存放到 S6,S7,S8,S9 和 S10 单元中。 -
36、编写一个有主程序和子程序结构的程序模块。子程序的参数是一个 N 字节数组的首地址
TABLE,数 N 及字符CHAR。要求在 N 字节数组中查找字符CHAR,并记录该字符出现的次数。主程序则要求从键盘接收一串字符以建立字节数组TABLE,并逐个显示从键盘输入的每个字符CHAR以及它在TABLE数组中出现的次数。(为简化起见,假设出现次数 ≤ 15,可以用 16 进制形式把它显示出来。) -
37、编写一个子程序嵌套结构的程序模块,分别从键盘输入姓名及 8 个字符的电话号码,并以一定的格式显示出来。
主程序TELIST: -
显示提示符
INPUT NAME:; -
调用子程序
INPUT_NAME输入姓名; -
显示提示符
INPUT A TELEPHONE NUMBER:; -
调用子程序
INPHONE输入电话号码; -
调用子程序
PRINTLINE显示姓名及电话号码。
子程序INPUT_NAME: -
调用键盘输入子程序
GETCHAR,把输入的姓名存放在INBUF缓冲区中; -
把
INBUF中的姓名移入输出行OUTNAME。
子程序INPHONE: -
调用键盘输入子程序
GETCHAR,把输入的 8 位电话号码存放在INBUF缓冲区中; -
把
INBUF中的号码移入输出行OUTPHONE。
子程序PRINTLINE:
显示姓名及电话号码,格式为:
NAME TEL.
XXX XXXXXXXX
-
38、编写子程序嵌套结构的程序,把整数分别用二进制和八进制形式显示出来。
主程序BANDO:把整数字变量VAL1存入堆栈,并调用子程序PAIRS;
子程序PAIRS:从堆栈中取出VAL1;调用二进制显示程序OUTBIN显示出与其等效的二进制数;输出 8 个空格;调用八进制显示程序OUTOCT显示出与其等效的八进制数;调用输出回车及换行符子程序。 -
39、假定一个名为
MAINPRO的程序要调用子程序SUBPRO,试问:
(1)MAINPRO中的什么指令告诉汇编程序SUBPRO是在外部定义的?
(2)SUBPRO怎么知道MAINPRO要调用它? -
40、定义宏指令
FINSUM:比较两个数 X 和 Y (X、Y为数,而不是地址),若 X > Y 则执行SUM←X+2*Y;否则执行SUM←2*X+Y。
All codes in this repository are licensed under the terms you may find in the file named "LICENSE" in this directory.