习题一
1.1把下列2、8、16进制数转换成为十进制数
(1)(1011011)2(2)(0.10110)2(3)(111111.01)2(4)(1000001.11)2(5)(377)8(6)(0.24)8(7)(3FF)16(8)(2A.4)16
解:(1)(1011011)2=64+16+8+2+1=91
另解:原式=(5B)16=5×16+11=91
(2)(0.10110)2=0.5+0.125+0.0625=0.6875
(3)(111111.01)2=32+16+8+4+2+1+0.25=63.25
另解:原式=(1000000-1+0.01)2=64-1+0.25=63.25
(4)(1000001.11)2=64+1+0.5+0.25=65.75
(5)(377)8=3×64+7×8+7=255
另解:原式=(400-1)8=4×64-1=255
(6)(0.24)8=2×0.125+4×0.015625=0.3125
(7)(3FF)16=3×256+15×16+15=1023
另解:原式=(400-1)16=4×256-1=1023
(8)(2A.4)16=2×16+10+4×0.0625=42.25
另解:原式=2×16+10+4÷16=42.25
1.2 把下列十进制数转换为2、16进制数
(1)(127)10(2)(33)10(3)(0.3)10(4)(0.625)10
(5)(1023.5)10(6)(377)10(7)(1/1024)10(8)(377/32)10解:(1)(127)10 =64+32+16+8+4+2+1= (111 1111)2=(7F)16
另解:原式=(128-1)10=(1000 0000-1)2=(111 1111)2=(7F)16
(2)(33)10=32+1= (10 0001)2=(21)16
(3)(0.3)10 = (0.0100 1100 1……)2=(0.4CCC……)16
(4)(0.625)10= 0.5+0.125=(0.101)2=(0.A)16
(5)(1023.5)10 = 512+256+128+64+32+16+8+4+2+1+0.5
=(11 1111 1111.1)2=(3FF.8)16
(6)(377)10 =256+64+32+16+8+1=(1 0111 1001)2=(179)16
(7)(1/1024)10=(0.0000 0000 01)2=(0.004)16
(8)(377/32)10=(256+64+32+16+8+1)÷(32)= (101111001)2÷(100000)2
=(1011.11001)2=(0B.C1)16
1.3 把下列二进制数转换为十六进制数
(1)(100011)2(2)(0.11101)2(3)(11111.11)2(4)(0.00101)2解:(1)(100011)2=(10?0011)2=23H
(2)(0.11101)2=(0.1110?1000)2=0.E8H
(3)(11111.11)2=(1?1111.1100)2=1F.CH
(4)(0.00101)2=(0.0010?1000)2=0.28H
1.4 把下列十六进制数转换为二进制数
(1)(3B6)16(2)(100)16(3)(80.2)16(4)(2FF.A)16
解:(1)(3B6)16=(0011 1011 0110)2
(2)(100)16 =(0001 0000 0000)2
(3)(80.2)16=(1000 0000.0010)2
(4)(2FF.A)16 =(0010 1111 1111.1010)2
1.5 如果用24b储存一个无符号数,这个数的范围是什么?如果储存的是一个补码表示的有符号数,那么这个数的范围又是什么?
答:如果用24b储存一个无符号数,这个数的范围应为:0~224-1
如果用24b储存一个补码表示的有符号数,这个数的范围应为:-223~+223-1
1.6 两个无符号数,它们的大小等于十进制数210和303,用N位二进制存储时,相加产生了进位,用N+1位二进制存储时,相加没有产生进位。这个N等于多少?为什么?
答:210+303=513,29<513<210,取N=9时,相加会产生进位,取N=10,相加就不会产生进位,因此,本题中N=9。
1.7 两个8位二进制无符号数相加后没有产生进位,符号标志SF=1,它们和应在什么范围内?如果SF=0,那么和又在什么范围内?
答:如果SF=1,它们的和应在27~28-1,也就是128~255之内。
如果SF=0,它们的和应在0~27-1,也就是0~127之内。
1.8 两个8位补码表示的有符号数相加时,什么情况下会使进位标志等于“1”?相减时,又是什么情况下会使借位标志等于“1”?答:两个8位补码表示的有符号数相加时,下列情况会使进位标志等于“1”:
两个负数相加;
两个异号数相加,和为正(不会产生溢出)。
两个8位补码表示的有符号数相减时,下列情况会使借位标志等于“1”:
两个同号数相减,差为负(不会产生溢出);
正数减负数(有可能产生溢出);
1.9 用符号“〉”把下面的数按从大到小的顺序“连接”起来
[X1]补=10110111 [X2]原=10110111 [X3]反=10110111 [X4]补=10110110 [X5]无符号数=10110111
解:X1=-0100 1001B, X2=-011 0111B, X3=-0100 1000B, X4=-0100 1010B, X5=+1011 0111B
因此:X5>X2>X3>X1>X4
1.10 用8位补码完成下列运算,用二进制“真值”的格式给出运算结果,并指出运算后CF、OF、ZF、SF、PF标志位的状态。
(1)127+126 (2)126-127 (3)-100-120 (4)-100-(-120)
解:(1)127+126
[127]补=0111 1111,[126]补=0111 1110,
[127+126]补=1111 1101,[127+126]=-0000 0011(溢出)
COZSP=01010
(2)126-127
[126]补=0111 1110,[-127]补=1000 0001,
[126-127]补=1111 1111,[126-127]=-000 0001
COZSP=10011
(3)-100-120
[-100]补=1001 1100,[-120]补=1000 1000,
[-100-120]补=0010 0100,[-100-120]=+0010 0100(溢出)
COZSP=01001
(4)-100-(-120)
[-100]补=1001 1100,[-120]补=1000 1000,[ [-120]补]求补=0111 1000,
[-100-(-120)]补=0001 0100,[-100-(-120)]=+0001 0100
COZSP=00001
1.11 把二进制代码1001011101011000分别“看作”是:
(1)二进制无符号数(2)二进制补码(3)压缩BCD码(4)非压缩BCD码
哪一种情况下它代表的“值”最大?
答:看作二进制无符号数时,它代表的“值”最大。
分析:看作二进制补码时,它代表一个负数,而其它的情况下,它均为正数。因此,看作二进制补码时,它代表的值最小。
把这组代码用十六进制数字形式写出:9758
对于无符号数,它的值等于十六进制的9758H;
对于压缩BCD码,它的值等于十进制的9758,显然小于9758H;
对于非压缩BCD码,它的值等于十进制的78,显然更小于9758H;
因此,看作二进制无符号数时,它代表的“值”最大。
1.12 CPU使用“寄存器”有什么好处?为什么?
答:CPU使用寄存器主要有两个好处:
(1)寄存器位于CPU内部,访问寄存器比访问内存储器速度快;
(2)寄存器数量大大少于内存储器单元个数,标识寄存器使用的二进制代码比标识内存储器单元使用的二进制代码少得多,可以缩短指令长度。
1.13 已知8086系统某存储单元物理地址为12345H,写出4个可以与它对应的“逻辑地址”。
答:可以与物理地址12345H对应的逻辑地址有:
1234H:0005H, 1230H:0045H, 1220H:0145H, 1224H:0105H, ……
1.14 已知8086系统某存储单元物理地址为12345H,可以与它对应的“逻辑地址”中,段基址最大值,最小值分别是多少?答:可以与物理地址12345H对应的逻辑地址中,段基址的最大值为1234H,最小值为0235H。
分析:偏移地址取最大值时,对应的段基址为最小。偏移地址可选的最大值为0FFF5H(最后一位必须为5),因此最小的段基址=(12345H-0FFF5H)/10H=0235H。
偏移地址取最小值时,对应的段基址最大。偏移地址可选的最小值为0005H(最后一位必须为5),因此最大的段基址=(12345H-0005H)/10H=1234H。
1.15 8086微机最多可以有多少个不同的“段基址”?为什么?
答:由于段基址由16位二进制数表示,因此可以有216=65536个不同的段基址。
1.16 在图1-6中,假设已有(R1)=X,(R2)=Y,分别用它的机器指令和符号指令写出计算R0←4X+2Y的程序。想一想,怎样做才能尽量减少指令数量?
答:假设已有(R1)=X,(R2)=Y,可以编制如下计算R0←4X+2Y的程序:
符号指令机器指令注释
MOV R0, R1 1 000 00 01(81H)R0←X
ADD R0, R1 1 001 00 01(91H)R0←X+X
ADD R0, R2 1 001 00 10(92H)R0←2X+Y
ADD R0, R0 1 001 00 00(90H)R0←4X+2Y
减少指令的方法是先计算出2X+Y,然后再计算4X+2Y。可以有多种不同的写法。
1.17 什么是“逻辑地址”?什么是“线性地址”?什么是“物理地址”?它们如何转换?
答:由段的起始地址(段基址)或者段的编号和段内相对地址两部分表示的地址称为“逻辑地址”。
经过“分段机构”处理后,用一组二进制代码表示的地址称为“线性地址”。
经过“分页机构”处理后,用一组二进制代码表示的存储单元的“真实”的地址称为“物理地址”。物理地址的位数等于地址总线的宽度。
工作在实地址模式下的80X86MPU不使用线性地址,物理地址=段基址×16+段内偏移地址。
80X86MPU工作在保护模式下时,分段机构用段的编号在“段描述符表”中找到段的起始地址,加上偏移地址得到“线性地址”。
分页机构把线性地址从高位到低位分解为“页组地址:页地址:页内地址”三部分,由页组地址(页组号)查找“页组表”,获得该页组对应的“页表”首地址。然后用页地址(页号)去查“页表”,得到该页的起始地址,拼接上页内地址,得到“物理地址”。
保护模式下也可以关闭分页机构,此时线性地址等于物理地址。
1.18 32位80X86和16位80X86中央处理器的段寄存器有什么不同?
答:16位80X86CPU的段寄存器长度为16位,存放的是一个段起始地址的高16位。
32位80X86CPU的段寄存器长度仍然为16位,存放的是一个段在“段描述符表”中的序号,表的编号(对每一个程序,有两张段描述符表)和这个段的优先级别。
1.19 叙述“保护模式”和“虚拟8086方式”之间的关系。
答:保护模式是32位80X86MPU的工作方式,对当前运行的所有任务实施保护。
虚拟8086方式是保护模式下某一个任务的工作模式,该任务使用类似于实地址方式下的物理地址产生方式,使用1MB 的虚拟内存空间,主要用于运行8086程序。
1E H
30H
41H
42H
43H
0F F H
00H
0C A H
0F F H
00H
0F E H
0F F H
44H
43H 0020H
002E H X Y
习题二
2.1 某数据段内有如下数据定义:
X db 30, 30H, …A BC?, 2-3, ?, 11001010B
dw 0FFH,-2, “CD”
Y dd 20 dup(15, 3 dup(?), 0)
Z db 3 dup(?)
W dw Z-X
假设变量X的偏移地址为20H。
(1)按照图2-1的格式写出变量X各数据在内存中的具体位置和相关内存单元的值。
(2)写出变量Y,Z的偏移地址。
(3)写出变量W的值
答:(1)变量X各数据在内存中的具体位置和相关内存单元的值如右图。
(2)变量Y的偏移地址为002EH;
变量Z的偏移地址为002EH+4×5×20=01BEH
(3)变量W的值等于变量Z和X偏移地址之差
01BEH-0020H=019EH
它等于变量X、Y所占用内存单元的字节数。
2.2 80x86指令系统有哪几种类型的指令操作数?比较使用不同类型操作数后的指令长度
和指令执行时间。
答:80X86指令系统按照长度划分,有以下四种指令操作数:
(1)寄存器操作数,指令短,执行速度快;
(2)立即操作数,指令较长,执行速度快;
(3)寄存器间接寻址和基址变址寻址表示的内存储器操作数,这类指令长度较短,执行速度较慢(需要访问存储器);
(4)直接地址,寄存器相对寻址,相对的基址变址寻址表示的内存储器操作数,这类指令长度较长,执行速度较慢(需要计算物理地址,访问存储器)。
2.3 下列指令的源操作数段基址在哪个段寄存器中?
(1)MOV AX, [BP][SI] (2)MOV AX, CS:8[DI]
(3)MOV AX, 2[EBP*1](4)MOV AX, FS:4[ESP]
(5)MOV AX, 2[EBP][EAX] (6)MOV AX, [ECX][EBP*4]
(7)MOC AX, [EDX][EBP] (8)MOV AX, ES:10[EBP][EAX*2]
答:各指令源操作数段基址使用的段寄存器如下:
(1)SS(2)CS(3)SS(4)FS
(5)SS(6)DS(7)DS(8)ES
2.4 判断下列指令是否正确。若不正确,指出错误原因
(1)MOV AX, [EBX] (2)MOV SI, DL
(3)MOV EBP, [ESP][EAX*3](4)LEA AX, 3006H
(5)MOV [BP][DI], 0 (6)MOV [SI], [DI]
(7)MOV ES, 1000H (8)MOV AX, X+2
(9)MOV AX, CX+2 (10)MOV [EAX][EAX*2], AL
答:(1)指令MOV AX, [EBX] 是正确的。
(2)指令MOV SI, DL是错误的,两个操作数类型不匹配。
(3)指令MOV EBP, [ESP][EAX*3] 是错误的,比例因子不能为3。
(4)指令LEA AX, 3006H是错误的,LEA指令的源操作数必须为内存操作数。
(5)指令MOV [BP][DI], 0是错误的,操作数类型无法确定。
(6)指令MOV [SI], [DI] 是错误的,不能同时出现两个内存操作数。
(7)指令MOV ES, 1000H是错误的,装载段寄存器时,源操作数不能为立即数。
(8)如果“X”是用常数表达式定义的符号(例如:X EQU5+6),或者是用“DW”定义的内存变量,指令MOV AX, X+2是正确的。否则这条指令是错误的。
(9)指令MOV AX, CX+2是错误的,源操作数表达式CX+2不是一个可以直接计算的“常数表达式”。
(10)指令MOV [EAX][EAX*2], AL是正确的。
2.5 现有(DS)=2000H ,(BX)=0100H,(SI)=0002H,(20100H)=12H,(20101H)=34H,(20102H)=56H,(20103H)=78H,(21200H)=2AH,(21201H)=4CH,(21202H)=0B7H,(21203H)=65H,说明下列指令执行后AX寄存器的内容。
(1)MOV AX, 1200H
(2)MOV AX, BX
(3)MOV AX, [1200H]
(4)MOV AX, [BX]
(5)MOV AX, 1100H[BX]
(6)MOV AX, [BX][SI]
(7)MOV AX, 1100H[BX][SI]
答:(1)指令MOV AX, 1200H执行后,(AX)=1200H (立即数操作数)。
(2)指令MOV AX, BX执行后,(AX)=0100H (寄存器操作数)。
(3)指令MOV AX, [1200H] 执行后,(AX)=4C2AH(直接地址,EA=1200H)
(4)指令MOV AX, [BX] 执行后,(AX)=3412H(寄存器间接寻址,EA=0100H)
(5)指令MOV AX, 1100H[BX] 执行后,(AX)= 4C2A H(相对地址,EA=1200H)
(6)指令MOV AX, [BX][SI] 执行后,(AX)=7856H(基址变址寻址,EA=0102H)
(7)指令MOV AX, 1100H[BX][SI] 执行后,(AX)=65B7H
(相对基址变址寻址,EA=1202H)
2.6 已经定义字符串MYSTRING如下:
MYSTRING DB …A Sample f or addressing.?
用适当的指令把这个字符串的第5,12个字符(注:第0个字符是?A?)送入BX寄存器。
答:可以用如下两条指令完成:
MOV BL, MY STRING[5]
MOV BH, MYSTRING[12]
2.7 下面两条指令的功能有什么区别?
MOV AX, BX
MOV AX, [BX]
答:指令“MOV AX, BX”把BX寄存器的内容装入到AX中。
指令“MOV AX, [BX]”把内存储器一个字的内容装入AX寄存器。该字的段基址在D S中,偏移地址在BX中。
2.8 已经定义数据段如下:
DA TA SEGMENT
NUM=56
X DB NUM
Y DB 27
Z DW 148
DA TA ENDS
指出下列指令中的错误:
(1)MOV Y, X(2)MOV BL, 04B8H
(3)MOV AL, Z (4)MOV [BX], 3
(5)MOV [BX], [DI] (6)MOV DS, DA TA
(7)MOV NUM, AX (8)MOV ES, D S
(9)MOV AX, FLAGS (10)MOV CS, AX
答:(1)指令MOV Y, X同时出现了两个存储器操作数。
(2)指令MOV BL, 04B8H 操作数类型不匹配(04B8H是16位立即数,BL是8位寄存器)。
(3)指令MOV AL, Z 操作数类型不匹配(Z是16位操作数,BL是8位寄存器)。
(4)指令MOV [BX], 3 操作数类型不能确定。
(5)指令MOV [BX], [DI] 出现了两个存储器操作数。
(6)指令MOV DS, DA TA不能把立即数装入段寄存器。
(7)指令MOV NUM, AX 立即数不能用作目的操作数。
(8)指令MOV ES, D S 不能在段寄存器之间直接传输。
(9)指令MOV AX, FLAGS中,FLAGS寄存器只能隐含在少量指令中使用。
(10)指令MOV CS, AX中,CS寄存器不能用作目的操作数。
2.9 用适当的指令,把下面字符串STRING中的“&”字符用空格代替。
STRING DB “The Date is FEB&03”
答:可以使用如下指令:
MOV STRING[15], 20H ; 20H是空格的A SCII代码
习题三
3.1 根据以下要求,写出对应的汇编语言指令
(1)把BX和DX寄存器内容相加,结果存入DX寄存器。
(2)使用BX和SI寄存器进行基址变址寻址,把存储器中一字节内容与AL内容相加,结果存入存储单元。
(3)用寄存器BX和位移量0B2H的寄存器相对寻址方式,把存储器中一个双字与ECX相加,结果存入ECX。
(4)用偏移地址1020H直接寻址,把存储单元一个字内容与立即数3相加,结果存入存储单元。
(5)将AL寄存器内容与立即数120相加,结果存入AL寄存器。
答:(1)ADD DX, BX
(2) ADD [BX][SI], AL
(3) ADD ECX, [BX+0B2H]
(4) ADD WORD PTR[1020H], 3
(5) ADD AL, 120
3.2 求以下各十六进制数与62A8H之和,并根据结果写出标志位SF、CF、ZF、O F的值。
(1)1234H (2)4321H (3)0CFA0H (4)9D60H (5)0FFFFH
答:(1)1234H+62A8H=74DCH SCZO= 0000
(2)4321H+62A8H=0A5C9H SCZO= 1001
(3)0CFA0H+62A8H=3248H SCZO= 0100
(4)9D60H +62A8H=0008H SCZO= 0100
(5)0FFFFH+62A8H=62A7H SCZO= 0100
3.3求以下各十六进制数与4AE0H之差,并根据结果写出标志位SF、CF、ZF、OF的值。
(1)1234H (2)5D90H (3)9076H (4)0EA04H (5)0FFFFH
答:
(1)1234H-4AE0H=0C754H SCZO= 1100
(2)90H-4AE0H=12B0H SCZO= 0000
(3)9076H-4AE0H=4597H SCZO= 0001
(4)0EA04H-4AE0H=9F24H SCZO= 1000
(5)0FFFFH-4AE0H=0B51FH SCZO= 1000
3.4 写出执行以下计算的指令序列,其中各变量均为16位有符号数。
(1)Z←W+(Z-X)
(2)Z←W-(X+6)-(R+9)
(3)Z←(W*X)/(Y+6), R←余数
(4)Z←(W-X)/(5*Y)*2
解:
(1) MOV AX, W
MOV BX, Z
SUB BX, X
ADD AX, BX
MOV Z, AX
(2) MOV AX, W
MOV BX, X
ADD BX, 6
SUB AX, BX
MOV BX, R
ADD BX, 9
SUB AX, BX
MOV Z, AX
(3) MOV AX, W
IMUL X
MOV BX, Y
ADD BX, 9
IDIV BX
MOV Z, AX
MOV R, DX
(4) MOV AX, Y
MOV BX, 5
IMUL BX
MOV BX, AX
MOV AX, W
SUB AX, X
MOV CX, 2
IMUL CX
IDIV BX
MOV Z, AX
3.5 一个双字长有符号数存放在DX(高位)AX(低位)中,写出求该数相反数的指令序列。
结果仍存入DX,AX寄存器
解:NOT DX ;首先将(DX, AX)取反
NOT AX
ADD AX, 1 ;最低位加1,注意:不能用INC指令
ADC DX, 0 ;把进位(如果有)传递到高位
3.6 指令DEC BX和SUB BX, 1的执行结果一样吗?请分析。
解:指令DEC BX和SU B BX, 1分别执行后,BX寄存器内的值相同,但是CF标志位的状
态可能不同,这是由于DEC指令执行后不改变CF的状态。
3.7 已知内存变量X, Y, Z均由“DB”伪操作定义,按照以下要求,使用MOVZX或MOVSX指令进行位数扩展,求三个数的
16b和。
(1)如果X,Y,Z为无符号数
(2)如果X,Y,Z为有符号数
解:(1)MOVZX AX, X
MOVZX BX, Y
ADD AX, BX
MOVZX BX, Z
ADD AX, BX
(2) MOVSX AX, X
MOVSX BX, Y
ADD AX, BX
MOVSX BX, Z
ADD AX, BX
3.8 内存缓冲区BU FFER定义如下,按照要求,写出指令序列
BUFFER DB 20 DUP(?)
(1)将缓冲区全部置为0,并使执行时间最短
(2)将缓冲区全部置为空格字符(ASCII代码20H),使用的指令条数最少(3)将缓冲区各字节依次设置为0,1,2,3,4,……,19
(4)将缓冲区各字节依次设置为0,-1,-2,-3,-4,……,-19
(5)将缓冲区各字节依次设置为30,29,28,27,……,11
(6)将缓冲区各字节依次设置为0,2,4,6,8,……,38
(7)将缓冲区各字节依次设置为0,1,2,3,0,1,2,3,……,3
解:
(1) XOR EAX, EAX
MOV DWORD PTR [BUFFER], EAX
MOV DWORD PTR [BUFFER+4], EAX
MOV DWORD PTR [BUFFER+8], EAX
MOV DWORD PTR [BUFFER+12], EAX
MOV DWORD PTR [BUFFER+16], EAX
(2) MOV AL, 20H
MOV CX, 20
LEA BX, BU FFER
ONE:MOV [BX], AL
INC BX
LOOP ONE
(3) XOR BX, BX
MOV CX, 20
ONE:MOV BUFFER[BX], BL
INC BX
LOOP ONE
(4) XOR BX, BX
XOR AL, AL
MOV CX, 20
ONE:MOV BUFFER[BX], AL
INC BX
DEC AL
LOOP ONE
(5) XOR BX, BX
MOV AL, 30
MOV CX, 20
ONE:MOV BUFFER[BX], AL
INC BX
DEC AL
LOOP ONE
(6) XOR BX, BX
XOR AL, AL
MOV CX, 20
ONE:MOV BUFFER[BX], AL
INC BX
ADD AL, 2
LOOP ONE
(7) XOR BX, BX
MOV CX, 5
ONE:
MOV BUFFER[BX], 0
MOV BUFFER[BX+1], 1
MOV BUFFER[BX+2], 2
MOV BUFFER[BX+3], 3
ADD BX, 4
LOOP ONE
3.9 编写循环结构程序,进行下列计算,结果存入RESUL T内存单元
(1)1+2+3+4+5+6+ …… +100
(2)1+3+5+7+9+11+ …… +99
(3)2+4+6+8+10+ …… +100
(4)1+4+7+10+13+ …… +100
(5)11+22+33+44+ …… +99
解:
(1) CODE S EGMENT
ASSUME CS: CODE
RESULT DW ?
STAR T:
XOR AX, AX
MOV CX, 100
AGAIN:ADD AX, CX
LOOP AGAIN
MOV RESULT, AX
MOV AX, 4C00H
INT 21H
CODE E NDS
END STAR T
(2)CODE SEGMENT
ASSUME CS: CODE
RESULT DW ?
STAR T:
XOR AX, AX
MOV CX, 50
MOV BX, 1
AGAIN:ADD AX, BX
ADD BX, 2
LOOP AGAIN
MOV RESULT, AX
MOV AX, 4C00H
INT 21H
CODE E NDS
END STAR T
(3) CODE S EGMENT
ASSUME CS: CODE
RESULT DW ?
STAR T:
XOR AX, AX
MOV CX, 50
MOV BX, 2
AGAIN:ADD AX, BX
ADD BX, 2
LOOP AGAIN
MOV RESULT, AX
MOV AX, 4C00H
INT 21H
CODE E NDS
END STAR T
(4) CODE S EGMENT
ASSUME CS: CODE
RESULT DW ?
STAR T:
XOR AX, AX
MOV CX, 34
MOV BX, 1
AGAIN:ADD AX, BX
ADD BX, 3
LOOP AGAIN
MOV RESULT, AX
MOV AX, 4C00H
INT 21H
CODE E NDS
END STAR T
(5) CODE S EGMENT
ASSUME CS: CODE
RESULT DW ?
STAR T:
XOR AX, AX
MOV CX, 9
MOV BX, 11
AGAIN:ADD AX, BX
ADD BX, 11
LOOP AGAIN
MOV RESULT, AX
MOV AX, 4C00H
INT 21H
CODE E NDS
END STAR T
3.10 已知ARRA Y是5行5列的有符号字数组,编写程序,进行下列计算(假设和仍然为
16b,不会产生溢出)
(1)求该数组第4列所有元素之和(列号从0开始)
(2)求该数组第3行所有元素之和(行号从0开始)
(3)求该数组正对角线上所有元素之和
(4)求该数组反对角线上所有元素之和
解:假设数据段已定义如下:
DA TA SEGMENT
ARRA Y DW 1, 6, 9, 23,12 ;定义数组ARRA Y
DW 54, 23, 15, -92, 37 ;每一行5个数据
DW -99, 231, 76, 81, 90 ;共5行
DW 33, 67, 81, -99, 0 ;共计25个数据
DW 123, -52, 77, -180, 89
SUM DW ? ;SUM存放结果
DA TA ENDS
(1)CODE SEGMENT
ASSUME CS: CODE, DS: DA TA
STAR T: MOV AX, DA TA
MOV DS, AX
MOV AX, 0 ;累加器在循环之前清零
MOV CX, 5 ;计数器置初值
MOV SI, 4*2 ;第1行第4列元素在数组内的位移NEXT: ADD AX, ARRA Y[SI]
ADD SI, 5*2 ;SI指向下一行第4列元素
LOOP NEXT
MOV SUM, AX
MOV AX, 4C00H
INT 21H
CODE E NDS
END STAR T
(2)CODE SEGMENT
ASSUME CS: CODE, DS: DA TA
STAR T: MOV AX, DA TA
MOV DS, AX
MOV AX, 0 ;累加器在循环之前清零
MOV CX, 5 ;计数器置初值
MOV SI, 3*5*2 ;第3行第0列元素在数组内的位移NEXT: ADD AX, ARRA Y[SI]
ADD SI, 2 ;SI指向本行下一列元素
LOOP NEXT
MOV SUM, AX
MOV AX, 4C00H
INT 21H
CODE E NDS
END STAR T
(3)CODE SEGMENT
ASSUME CS: CODE, DS: DA TA
STAR T: MOV AX, DA TA
MOV DS, AX
MOV AX, 0 ;累加器在循环之前清零
MOV CX, 5 ;计数器置初值
MOV SI, 0 ;第0行第0列元素在数组内的位移NEXT: ADD AX, ARRA Y[SI]
ADD SI, 5*2+2 ;SI指向正对角线上下一个元素
LOOP NEXT
MOV SUM, AX
MOV AX, 4C00H
INT 21H
CODE E NDS
END STAR T
(4)CODE SEGMENT
ASSUME CS: CODE, DS: DA TA
STAR T: MOV AX, DA TA
MOV DS, AX
MOV AX, 0 ;累加器在循环之前清零
MOV CX, 5 ;计数器置初值
MOV SI, 4*2 ;第0行第4列元素在数组内的位移NEXT: ADD AX, ARRA Y[SI]
ADD SI, (5-1)*2 ;SI指向反对角线上下一个元素
LOOP NEXT
MOV SUM, AX
MOV AX, 4C00H
INT 21H
CODE E NDS
END STAR T
3.11 编写程序,利用公式:N2=1+3+5+ …… +(2N-1)计算N2的值,假设N=23。
解:DA TA SEGMENT
N DW 23
SQUARE DW ? ;存放结果
DA TA ENDS
CODE S EGMENT
ASSUME CS: CODE, DS: DA TA
STAR T: MOV AX, DA TA
MOV DS, AX
MOV CX, N ;循环计数器置初值
XOR AX, AX ;累加器清零
MOV BX, 1 ;数列第一项
ONE: ADD AX, BX
ADD BX, 2
LOOP ONE
MOV SQUARE, AX
MOV AX, 4C00H
INT 21H
CODE E NDS
END STAR T
3.12 变量X, Y, Z均为一字节压缩BCD码表示的十进制数,写出指令序列,求它们的和(用2字节压缩BCD码表示)。
解:XOR AX, AX ;清AX,用于存放2字节结果
MOV AL, X
ADD AL, Y ;完成X+Y
DAA ;压缩BCD码加法调整
ADC AH, 0 ;把可能的进位收集到AH中
;AH中最大的可能值为2,因此不需要BCD加法调整
ADD AL, Z ;完成X+Y+Z
DAA ;压缩BCD码加法调整
ADC AH, 0 ;把可能的进位收集到AH中
;计算完成,结果(2字节压缩BCD码)在AX中
3.13 数组LIST1内存有20个非压缩BCD码表示的单字节十进制数,写出完整程序,求这20个BCD数之和,结果(非压缩
BCD码)存入SUM1双字单元。
解: CODE SEGMENT
ASSUME CS: CODE
LIST1 DB …6705762998?;20个非压缩BCD数
DB …4322687310?
SUM1 DD ? ;存放结果(20个数之和)
STAR T: XOR AX, AX ;累加器清零
MOV CX, 20 ;循环计数器置初值
LEA BX, LIST1 ;地址指针置初值
ONE: ADD AL, CS:[BX] ;加入一个非压缩BCD数
AAA ;调整,结果在AH(百位、十位),AL(个位)中
INC BX ;修改指针
LOOP ONE ;循环控制
MOV BYTE PTR SUM1, AL ;保存个位
MOV AL, AH
MOV AH, 0 ;百位、十位(二进制)存入AX
AAM ;分解百位到AH,十位到AL
MOV WORD PTR SUM1+1, AX ;保存百位、十位
MOV BYTE PTR SUM1+3, 0 ;千位清零(和最大为9*20=180)
MOV AX, 4C00H
INT 21H
CODE E NDS
END STAR T
3.14数组LIST2内存有20个压缩BCD码表示的单字节十进制数,写出完整程序,求这20个BCD数之和,结果(压缩BCD
码)存入SUM2双字单元。
解: CODE SEGMENT
ASSUME CS: CODE
LIST2 DB 12H, 34H, 56H, 15H, 82H, 52H, 48H, 19H, 31H, 63H
DB 22H, 33H, 44H, 55H, 66H, 77H, 88H, 99H, 11H, 39H
SUM2 DD ?
STAR T: XOR AX, AX ;累加器清零
XOR BX, BX ;地址指针置初值
MOV CX, 20 ;循环计数器置初值
ONE: ADD AL, LIST2[BX] ;加入一个压缩BCD数
DAA ;调整
XCHG AH, AL ;交换AH和AL
ADC AL, 0 ;收集进位(百位、千位)
DAA ;高位(百位、千位)调整
XCHG AH, AL ;恢复AH和AL
;(AH)=千位、百位,(AL)=十位、个位
INC BX ;修改指针
LOOP ONE ;循环控制
MOV WORD PTR SUM2, AX ;保存千、百、十、个位
MOV WORD PTR SUM2+2, 0;高位清零
MOV AX, 4C00H
INT 21H
CODE E NDS
END STAR T
3.15 数组LIST3内存有20个压缩BCD码表示的双字节十进制数,写出完整程序,求这20
个BCD数之和,结果(压缩BCD码)存入SUM3双字单元。
解: CODE SEGMENT
ASSUME CS: CODE
LIST3 DW 1234H, 3456H, 5678H, 1523H, 8263H,
DW 5234H, 4856H, 1926H, 3177H, 6389H
DW 2211H, 3322H, 4433H, 5544H, 6655H
DW 7766H, 8877H, 9988H, 1167H, 3944H
SUM3 DD ?
STAR T: XOR DX, DX
XOR AX, AX ;累加器清零
LEA BX, LIST3 ;地址指针置初值
MOV CX, 20 ;循环计数器置初值
ONE: ADD AL, CS:[BX] ;加入第一字节压缩BCD数(十位、个位)
DAA ;调整
XCHG AH, AL ;交换AH和AL
INC BX ;修改指针,指向高位字节(千位、百位)
ADC AL, CS:[BX] ;高位累加,并收集低位进位
DAA ;高位(百位、千位)调整
XCHG AH, AL ;恢复AH和AL
;(AH)=千位、百位,(AL)=十位、个位INC BX ;修改指针
XCHG DX, AX ;交换AX和DX
ADC AL, 0 ;收集千位上的进位
DAA ;调整,得到和的十万位和万位
XCHG DX, AX ;恢复DX和AX
LOOP ONE ;循环控制
MOV WORD PTR SUM3, AX ;保存千、百、十、个位
MOV WORD PTR SUM3+2, DX ;保存十万位和万位
MOV AX, 4C00H
INT 21H
CODE E NDS
END STAR T
3.16 设(BX)=0E3H,变量V ALUE中存放内容为79H,指出下列指令单独执行后的结果。
(1)XOR BX, V ALUE
(2)AND BX, V ALUE
(3)OR BX, V ALUE
(4)XOR BX, 0FFH
(5)AND BX, BX
(6)AND BX, 0
答:
(1)指令“XOR BX, V ALUE”执行后,(BX)= 009A H
(2)指令“AND BX, V ALUE”执行后,(BX)= 0061H
(3)指令“OR BX, V ALUE”执行后,(BX)= 00FB H
(4)指令“XOR BX, 0FFH”执行后,(BX)= 001C H
(5)指令“AND BX, BX”执行后,(BX)= 00E3H
(6)指令“AND BX, 0”执行后,(BX)= 0000H
3.17 某密码的加密规则为:‘0’→‘A’,‘1’→‘B’,‘2’→‘C’,……。按照以下要求编写程序。
(1)把明文“96541833209881”翻译为密文。
(2)把密文“JJBDAHCFFGA”翻译成明文。
答:
(1)明文“96541833209881”翻译为密文。
CODE S EGMENT
ASSUME CS: CODE
TEXT1 DB …96541833209881?
TEXT2 DB 14 DUP(?)
STAR T:
MOV BX, 0
MOV CX, 14
NEXT:
MOV AL, TEXT1[BX];取出一字节明文
ADD AL, …A?-…0?;转换成密文
MOV TEXT2[BX], AL ;保存
INC BX
LOOP NEXT
MOV AX, 4C00H
INT 21H
CODE E NDS
END STAR T
(2)密文“JJBDAHCFFGA”翻译成明文。
CODE S EGMENT
ASSUME CS: CODE
TEXT1 DB …JJBDAHCFFGA?
TEXT2 DB 11 DUP(?)
STAR T:
MOV BX, 0
MOV CX, 11
NEXT:
MOV AL, TEXT1[BX];取出一字节密文
SUB AL, …A?-…0?;转换成明文
MOV TEXT2[BX], AL ;保存
INC BX
LOOP NEXT
MOV AX, 4C00H
INT 21H
CODE E NDS
END STAR T
3.18 编写程序,从键盘上输入一行明文,按照题3.17的规则翻译成密文,向显示器输出。
答:DA TA SEGMENT
MESS DB 0DH, 0AH, “Input some text please : $”
OUTMESS DB 0DH, 0AH, …The text af ter convert :?
BUFFER DB 81, ?, 81 DUP(?)
DA TA ENDS
CODE S EGMENT
ASSUME CS: CODE, DS: DA TA
STAR T:
MOV AX, DA TA
MOV DS, AX
LEA DX, MESS
MOV AH, 09H
INT 21H ;输出提示信息
LEA DX, BUFFER
MOV AH, 0AH
INT 21H ;输入一行明文
MOV CL, BUFFER+1
MOV CH, 0 ;输入字符个数送CX
LEA BX, BU FFER+2 ;首字符地址送BX
NEXT: MOV AL, [BX]
ADD AL, …A?-…0?;将一字节明文转换成密文
MOV [BX], AL ;保存
INC BX
LOOP NEXT
MOV BYTE PTR[BX], …$?;送字符串结束标记
MOV WORD PTR BU FFER, 2020H ;缓冲区前2字节改为空格
LEA DX, OUTMESS
MOV AH, 09H
INT 21H ;输出转换以后的结果
MOV AX, 4C00H
INT 21H
CODE ENDS
END STAR T
3.19 变量X用D T定义,存有80b有符号数,编写程序,求X的相反数,存入同样用D T定义的变量Y。答:CODE SEGMENT
ASSUME CS: CODE
X DT 1234567890H
Y DT ?
STAR T:
MOV CX, 10 ;循环计数器置初值
XOR BX, BX;地址指针置初值
ONE:
MOV AL, BY TE PTR X[BX]
NOT AL ;X的一字节内容取反
MOV BYTE PTR Y[BX] ;存入Y的一个字节内
INC BX
LOOP ONE
ADD BYTE PTR Y, 1 ;Y的低位字节加1
LEA BX, Y+1 ;从Y的第2字节开始处理
MOV CX, 9 ;共9个字节
TWO:
ADC BYTE PTRCS: [BX], 0 ;收集低位来的进位
INC BX ;修改指针
LOOP TWO ;循环控制
MOV AX, 4C00H
INT 21H
CODE ENDS
END STAR T
3.20 编写程序,使用库子程序,从键盘上输入8个有符号字数据,求它们的和,以十进制
格式输出。
答:
INCLUDE YLIB.H
DA TA SEGEMNT
MESS1 DB 0DH, 0AH, …Input a number please : $?
MESS2 DB 0DH, 0AH, …The sum is : $?
DA TA ENDS
CODE S EGMENT
ASSUME CS: CODE, DS: DA TA
STAR T:
MOV AX, DA TA
MOV DS, AX
XOR BX, BX ;BX用作累加器,清零
MOV CX, 8 ;循环计数器置初值
AGAIN:
LEA DX, MESS1
CALL READINT ;输入一个数据(在AX中)
ADD BX, AX ;累加
LOOP AGAIN