9299.net
大学生考试网 让学习变简单
当前位置:首页 >> 工学 >>

汇编答案

汇编答案


汇编语言程序设计 简明教程习题解答 主 编:杨文显 副主编:宓 双 胡建人 电 子 工 业 出 版 社 汇编语言程序设计简明教程 习题解答 主 编:杨文显 副主编:宓 双 胡建人 电 子 工 业 出 版 社 习题一 把下列 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<513X2>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 使用寄存器主要有两个好处: 寄存器位于 CPU 内部,访问寄存器比访问内存储器速度快; 寄存器数量大大少于内存储器单元个数,标识寄存器使用的二进制代码比标识内存储器单元 使用的二进制代码少得多,可以缩短指令长度. 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 程序. 习题二 2.1 某数据段内有如下数据定义: X db 30, 30H, 'ABC', 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. 按照图 2-1 的格式写出变量 X 各数据在内存中的具体位置和相关内存单元的值. 写出变量 Y,Z 的偏移地址. 写出变量 W 的值 答:(1)变量 X 各数据在内存中的具体位置和相关内存单元的值如右图. 变量 Y 的偏移地址为 002EH; 变量 Z 的偏移地址为 002EH+4×5×20=01BEH 变量 W 的值等于变量 Z 和 X 偏移地址之差 01BEH-0020H=019EH 它等于变量 X,Y 所占用内存单元的字节数. 2.2 80x86 指令系统有哪几种类型的指令操作数 比较使用不同类型操作数后的指令长度和 指令执行时间. 答:80X86 指令系统按照长度划分,有以下四种指令操作数: 寄存器操作数,指令短,执行速度快; 立即操作数,指令较长,执行速度快; 寄存器间接寻址和基址变址寻址表示的内存储器操作数,这类指令长度较短,执行速度较慢 (需要访问存储器); 直接地址,寄存器相对寻址,相对的基址变址寻址表示的内存储器操作数,这类指令长度较长, 执行速度较慢(需要计算物理地址,访问存储器). 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 EQU 5+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)= 4C2AH(相对地址,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 for addressing.' 用适当的指令把这个字符串的第 5,12 个字符(注:第 0 个字符是'A')送入 BX 寄存器. 答:可以用如下两条指令完成: MOV BL, MYSTRING[5] MOV BH, MYSTRING[12] 2.7 下面两条指令的功能有什么区别 MOV AX, BX MOV AX, [BX] 答:指令"MOV AX, BX"把 BX 寄存器的内容装入到 AX 中. 指令"MOV AX, [BX]"把内存储器一个字的内容装入 AX 寄存器.该字的段基址在 DS 中,偏移地址

在 BX 中. 2.8 已经定义数据段如下: DATA SEGMENT NUM=56 X DB NUM Y DB 27 Z DW 148 DATA ENDS 指出下列指令中的错误: (1)MOV Y, X (2)MOV BL, 04B8H (3)MOV AL, Z (4)MOV [BX], 3 (5)MOV [BX], [DI] (6)MOV DS, DATA (7) MOV NUM, AX (8)MOV ES, DS (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, DATA 不能把立即数装入段寄存器. (7)指令 MOV NUM, AX 立即数不能用作目的操作数. (8)指令 MOV ES, DS 不能在段寄存器之间直接传输. (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 是空格的 ASCII 代码 习题三 3.1 根据以下要求,写出对应的汇编语言指令 把 BX 和 DX 寄存器内容相加,结果存入 DX 寄存器. 使用 BX 和 SI 寄存器进行基址变址寻址,把存储器中一字节内容与 AL 内容相加,结果存入存储 单元. 用寄存器 BX 和位移量 0B2H 的寄存器相对寻址方式,把存储器中一个双字与 ECX 相加,结果存 入 ECX. 用偏移地址 1020H 直接寻址,把存储单元一个字内容与立即数 3 相加,结果存入存储单元. 将 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,OF 的值.

(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 答: 1234H-4AE0H=0C754H SCZO= 1100 90H-4AE0H=12B0H SCZO= 0000 9076H-4AE0H=4597H SCZO= 0001 0EA04H-4AE0H=9F24H SCZO= 1000 0FFFFH-4AE0H=0B51FH SCZO= 1000 3.4 写出执行以下计算的指令序列,其中各变量均为 16 位有符号数. Z←W+(Z-X) Z←W-(X+6)-(R+9) Z←(W*X)/(Y+6), R←余数 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 和 SUB BX, 1 分别执行后,BX 寄存器内的值相同,但是 CF 标志位的状 态可能不同,这是由于 DEC 指令执行后不改变 CF 的状态. 3.7 已知内存变量 X, Y, Z 均由"DB"伪操作定义,按照以下要求,使用 MOVZX 或 MOVSX 指令进 行位数扩展,求三个数的 16b 和. 如果 X,Y,Z 为无符号数 如果 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 内存缓冲区 BUFFER 定义如下,按照要求,写出指令序列 BUFFER DB 20 DUP( ) 将缓冲区全部置为 0,并使执行时间最短 将缓冲区全部置为空格字符(ASCII 代码 20H),使用的指令条数最少 将缓冲区各字节依次设置为 0,1,2,3,4,……,19 将缓冲区各字节依次设置为 0,-1,-2,-3,-4,……,-19 将缓冲区各字节依次设置为 30,29,28,27,……,11 将缓冲区各字节依次设置为 0,2,4,6,8,……,38 将缓冲区各字节依次设置为 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, BUFFER 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 编写循环结构程序,进行下列计算,结果存入 RESULT 内存单元 1+2+3+4+5+6+ …… +100

1+3+5+7+9+11+ …… +99 2+4+6+8+10+ …… +100 1+4+7+10+13+ …… +100 11+22+33+44+ …… +99 解: (1) CODE SEGMENT ASSUME CS: CODE RESULT DW START: XOR AX, AX MOV CX, 100 AGAIN: ADD AX, CX LOOP AGAIN MOV RESULT, AX MOV AX, 4C00H INT 21H CODE ENDS END START (2)CODE SEGMENT ASSUME CS: CODE RESULT DW START: 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 ENDS END START (3) CODE SEGMENT ASSUME CS: CODE RESULT DW START: 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 ENDS END START (4) CODE SEGMENT ASSUME CS: CODE RESULT DW START: 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 ENDS END START (5) CODE SEGMENT ASSUME CS: CODE RESULT DW START: 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 ENDS END START 3.10 已知 ARRAY 是 5 行 5 列的有符号字数组,编写程序,进行下列计算(假设和仍然为 16b,不会产生溢出) 求该数组第 4 列所有元素之和(列号从 0 开始) 求该数组第 3 行所有元素之和(行号从 0 开始) 求该数组正对角线上所有元素之和 求该数组反对角线上所有元素之和 解:假设数据段已定义如下: DATA SEGMENT ARRAY DW 1, 6, 9, 23,12 ;定义数组 ARRAY 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 存放结果 DATA ENDS (1)CODE SEGMENT ASSUME CS: CODE, DS: DATA START: MOV AX, DATA MOV DS, AX MOV AX, 0 ;累加器在循环之前清零 MOV CX, 5 ;计数器置初值 MOV SI, 4*2 ;第 1 行第 4 列元素在数组内的位移 NEXT: ADD AX, ARRAY[SI] ADD SI, 5*2 ;SI 指向下一行第 4 列元素 LOOP NEXT MOV SUM, AX MOV AX, 4C00H INT 21H CODE ENDS END START (2)CODE SEGMENT ASSUME CS: CODE, DS: DATA START: MOV AX, DATA MOV DS, AX MOV AX, 0 ;累加器在循环之前清零 MOV CX, 5 ;计数器置初值 MOV SI, 3*5*2 ;第 3 行第 0 列元素在数组内的位移 NEXT: ADD AX, ARRAY[SI] ADD SI, 2 ;SI 指向本行下一列元素 LOOP NEXT MOV SUM, AX MOV AX, 4C00H INT 21H CODE ENDS END START (3)CODE SEGMENT ASSUME CS: CODE, DS: DATA START: MOV AX, DATA MOV DS, AX MOV AX, 0 ;累加器在循环之前清零 MOV CX, 5 ;计数器置初值 MOV SI, 0 ;第 0 行第 0 列元素在数组内的位移 NEXT: ADD AX, ARRAY[SI]

ADD SI, 5*2+2 ;SI 指向正对角线上下一个元素 LOOP NEXT MOV SUM, AX MOV AX, 4C00H INT 21H CODE ENDS END START (4)CODE SEGMENT ASSUME CS: CODE, DS: DATA START: MOV AX, DATA MOV DS, AX MOV AX, 0 ;累加器在循环之前清零 MOV CX, 5 ;计数器置初值 MOV SI, 4*2 ;第 0 行第 4 列元素在数组内的位移 NEXT: ADD AX, ARRAY[SI] ADD SI, (5-1)*2 ;SI 指向反对角线上下一个元素 LOOP NEXT MOV SUM, AX MOV AX, 4C00H INT 21H CODE ENDS END START 3.11 编写程序,利用公式:N2=1+3+5+ …… +(2N-1)计算 N2 的值,假设 N=23. 解: DATA SEGMENT N DW 23 SQUARE DW ;存放结果 DATA ENDS CODE SEGMENT ASSUME CS: CODE, DS: DATA START: MOV AX, DATA 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 ENDS END START 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 个数之和) START: 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 ENDS END START 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 START: 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 ENDS END START 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 START: 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 ENDS END START 3.16 设(BX)=0E3H,变量 VALUE 中存放内容为 79H,指出下列指令单独执行后的结果. (1)XOR BX, VALUE (2)AND BX, VALUE (3)OR BX, VALUE (4)XOR BX, 0FFH (5)AND BX, BX (6)AND BX, 0 答: (1)指令"XOR BX, VALUE"执行后,(BX)= 009AH (2)指令"AND BX, VALUE"执行后,(BX)= 0061H (3)指令"OR BX, VALUE"执行后,(BX)= 00FBH (4)指令"XOR BX, 0FFH"执行后,(BX)= 001CH (5)指令"AND BX, BX"执行后,(BX)= 00E3H (6)指令"AND BX, 0"执行后,(BX)= 0000H 3.17 某密码的加密规则为:'0'→'A','1'→'B','2'→'C',…….按照以下要求编写程序. 把明文"96541833209881"翻译为密文. 把密文"JJBDAHCFFGA"翻译成明文. 答: 明文"96541833209881"翻译为密文. CODE SEGMENT ASSUME CS: CODE TEXT1 DB '96541833209881' TEXT2 DB 14 DUP( ) START: 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 ENDS END START 密文"JJBDAHCFFGA"翻译成明文. CODE SEGMENT ASSUME CS: CODE TEXT1 DB 'JJBDAHCFFGA '

TEXT2 DB 11 DUP( ) START: 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 ENDS END START 3.18 编写程序,从键盘上输入一行明文,按照题 3.17 的规则翻译成密文,向显示器输出. 答: DATA SEGMENT MESS DB 0DH, 0AH, "Input some text please : $" OUTMESS DB 0DH, 0AH, 'The text after convert :' BUFFER DB 81, , 81 DUP( ) DATA ENDS CODE SEGMENT ASSUME CS: CODE, DS: DATA START: MOV AX, DATA 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, BUFFER+2 ;首字符地址送 BX NEXT: MOV AL, [BX] ADD AL, 'A'-'0' ;将一字节明文转换成密文 MOV [BX], AL ;保存 INC BX LOOP NEXT MOV BYTE PTR[BX], '$' ;送字符串结束标记 MOV WORD PTR BUFFER, 2020H ;缓冲区前 2 字节改为空格 LEA DX, OUTMESS MOV AH, 09H INT 21H ;输出转换以后的结果

MOV AX, 4C00H INT 21H CODE ENDS END START 3.19 变量 X 用 DT 定义,存有 80b 有符号数,编写程序,求 X 的相反数,存入同样用 DT 定义的变 量 Y. 答: CODE SEGMENT ASSUME CS: CODE X DT 1234567890H Y DT START: MOV CX, 10 ;循环计数器置初值 XOR BX, BX ;地址指针置初值 ONE: MOV AL, BYTE 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 START 3.20 编写程序,使用库子程序,从键盘上输入 8 个有符号字数据,求它们的和,以十进制 格式输出. 答: INCLUDE YLIB.H DATA SEGEMNT MESS1 DB 0DH, 0AH, 'Input a number please : $' MESS2 DB 0DH, 0AH, 'The sum is : $' DATA ENDS CODE SEGMENT ASSUME CS: CODE, DS: DATA START: MOV AX, DATA MOV DS, AX XOR BX, BX ;BX 用作累加器,清零

MOV CX, 8 ;循环计数器置初值 AGAIN: LEA DX, MESS1 CALL READINT ;输入一个数据(在 AX 中) ADD BX, AX ;累加 LOOP AGAIN LEA DX, MESS2 MOV AX, BX CALL WRITEINT ;输出 8 个数的和 CALL CRLF MOV AX, 4C00H INT 21H CODE ENDS END START 3.21 编写程序,从键盘上输入 20 个十进制数字,求这些数字的和,向显示器输出. 答: INCLUDE YLIB.H DATA SEGEMNT MESS1 DB 0DH, 0AH, 'Input 20 decimal digits please : $' MESS2 DB 0DH, 0AH, 'Their sum is : $' DATA ENDS CODE SEGMENT ASSUME CS: CODE, DS: DATA START: MOV AX, DATA MOV DS, AX LEA DX, MESS1 MOV AH, 09H INT 21H ;输出提示信息 XOR BX, BX ;BX 用作累加器,清零 MOV CX, 20 ;循环计数器置初值 AGAIN: MOV AH, 01H INT 21H ;输入一个数字(在 AL 中) AND AL, 0FH ;转换成二进制数 ADD BL, AL ;累加 ADC BH, 0 LOOP AGAIN LEA DX, MESS2 MOV AX, BX CALL WRITEDEC ;输出 20 个数字的和 CALL CRLF MOV AX, 4C00H INT 21H

CODE ENDS END START 3.22 阅读以下程序,指出它的功能. MOV CL, 04 SHL DX, CL MOV BL, AH SHL AX, CL SHR BL, CL OR DL, BL 答:把 32 位二进制代码(DX, AX)联合左移 4 位. 3.23 已知(DX)=0B9H,(CL)=3,(CF)=1,确定下列指令单独执行以后 DX 寄存器的值. (1)SHR DX, 1 (2)SAR DX, CL (3)SHL DX, CL (4)SHL DL, 1 (5)ROR DX, CL (6)ROL DX, CL (7)SAL DH, 1 (8)RCL DX, CL (9)RCR DL, 1 答: (1)指令"SHR DX, 1"执行之后,(DX)= 005CH (2)指令"SAR DX, CL"执行之后,(DX)= 0017H (3)指令"SHL DX, CL"执行之后,(DX)= 05C8H (4)指令"SHL DL, 1"执行之后,(DX)= 0172H (5)指令"ROR DX, CL"执行之后,(DX)= 2017H (6)指令"ROL DX, CL"执行之后,(DX)= 05C8H (7)指令"SAL DH, 1"执行之后,(DX)= 00B9H (8)指令"RCL DX, CL"执行之后,(DX)= 05CCH (9)指令"RCR DL, 1"执行之后,(DX)= 00DCH 3.24 下面程序段执行完成后,BX 寄存器的内容是什么 MOV CL, 3 MOV BX, 0B7H ROL BX, 1 ROR BX, CL 答:上面程序段执行完成后,(BX)= 0C02DH 写程序,从键盘上输入一个 0~65535 之间的十进制无符号数,然后用二进制格式输出这个值. 例如,键盘输入"35",显示器输出"00000000 00100011". 答: INCLUDE YLIB.H DATA SEGEMNT MESS1 DB 0DH, 0AH, 'Input a unsigned decimal integer number please : $' MESS2 DB 0DH, 0AH, 'The number in binary is : $' DATA ENDS CODE SEGMENT

ASSUME CS: CODE, DS: DATA START: MOV AX, DATA MOV DS, AX LEA DX, MESS1 CALL READDEC ;输入一个无符号整数 MOV BX, AX ;转存入 BX LEA DX, MESS2 MOV AH, 09H INT 21H ;输出提示信息 MOV CX, 16 ;循环计数器置初值 AGAIN: SHL BX, 1 ;向左外移一位,进入 CF MOV DL, 30H ADC DL, 0 ;形成一位二进制数字的 ASCII 代码 MOV AH, 2 INT 21H ;输出一个二进制数字 LOOP AGAIN ;循环 16 次 CALL CRLF MOV AX, 4C00H INT 21H CODE ENDS END START 3.26 无符号数变量 X 用 DD 定义,编写程序,用十六进制格式输出变量 X 的值. 答: .386 DATA SEGEMNT USE16 X DD 36895471 ;一个 32B 长整数 MESS DB 0DH, 0AH, 'The X in hexdecimal is : $' HEXTAB DB '0123456789ABCDEF' DATA ENDS CODE SEGMENT USE16 ASSUME CS: CODE, DS: DATA START: MOV AX, DATA MOV DS, AX LEA DX, MESS MOV AH, 09H INT 21H ;输出前导信息 MOV ESI, X ;将 X 存入 ESI MOV CX, 8 ;循环计数器置初值 LEA BX, HEXTAB ;换码表首地址装入 BX AGAIN: ROL ESI, 4 ;把最高 4 位移到最低 4 位上 MOV AX, SI ;低 8 位转入 AL AND AX, 0004H ;清除高 4 位 XLAT ;转换成十六进制数字的 ASCII 代码

MOV DL, AL MOV AH, 2 INT 21H ;输出一个十六进制数字 LOOP AGAIN ;循环 16 次 MOV AX, 4C00H INT 21H CODE ENDS END START 3.27 从键盘上输入两个有符号字整数 A 和 B,计算并输出它们的和,差,积,商和余数. 答: INCLUDE YLIB.H DATA SEGEMNT MESS1 DB 0DH, 0AH, 'Input a integer number please : $' MESS2 DB 0DH, 0AH, 'The sum of 2 number is : $' MESS3 DB 0DH, 0AH, 'The difference of 2 number is : $' MESS4 DB 0DH, 0AH, 'The product of 2 number is : $' MESS5 DB 0DH, 0AH, 'The quotient of 2 number is : $' MESS6 DB 0DH, 0AH, 'The remainder of 2 number is : $' A DW B DW DATA ENDS CODE SEGMENT ASSUME CS: CODE, DS: DATA START: MOV AX, DATA MOV DS, AX LEA DX, MESS1 CALL READINT ;输入第一个有符号整数 MOV A, AX LEA DX, MESS1 CALL READINT ;输入第二个有符号整数 MOV B, AX ADD AX, A ;求两个数的和 LEA DX, MESS2 CALL WRITEINT ;输出两个数的和 MOV AX, A SUB AX, B ;求两个数的差 LEA DX, MESS3 CALL WRITEINT ;输出两个数的差 MOV AX, A IMUL B ;求两个数的积,假设仍然是 16 位 LEA DX, MESS4 CALL WRITEINT ;输出两个数的积 MOV AX, A CWD

IDIV B ;求两个数的商和余数 PUSH DX LEA DX, MESS5 CALL WRITEINT ;输出两个数的商 POP AX LEA DX, MESS6 CALL WRITEINT ;输出两个数的余数 CALL CRLF MOV AX, 4C00H INT 21H CODE ENDS END START 3.28 数组 ARRAY 中存有 10 个无符号字整数(元素序号 0~9),现在要删除其中的第 5 个元素. 编写程序,把第 6~9 个元素移到第 5~8 个元素的位置上,并把第 9 个元素清零. 答: DATA SEGEMNT ARRAY DW -386, 97, 213, 21, 77, -91, 56, 7, 123, 65 DATA ENDS CODE SEGMENT ASSUME CS: CODE, DS: DATA START: MOV AX, DATA MOV DS, AX MOV BX, 6*2 ;第六个元素在数组内的位移 MOV CX, 4 ;循环计数器置初值 AGAIN: MOV AX, ARRAY[BX] ;取出一个元素 MOV ARRAY[BX-2], AX ;向前移动一个位置 ADD BX, 2 ;修改指针 LOOP AGAIN ;循环 4 次 MOV ARRAY[BX], 0 ;最后一个元素清零 MOV AX, 4C00H INT 21H CODE ENDS END START 3.29 编写指令序列,把 AX 中的 16b 二进制分为 4 组,每组 4b,分别置入 AL,BL,CL,DL 中. 答: MOV DX, AX ;最低 4 位直接进入 DX MOV CX, 4 ROL AX, CL ;最高 4 位移入最低 4 位 PUSH AX ;压入堆栈保存(准备送入 AL) ROL AX, CL ;次高 4 位移入最低 4 位 MOV BX, AX ;送入 BL ROL AX, CL ;第 3 组 4 位移入最低 4 位 MOV CX, AX ;送入 CL POP AX ;从堆栈中弹出原最高 4 位 AND AX, 000FH ;清除高 12 位

AND BX, 000FH ;清除高 12 位 AND CX, 000FH ;清除高 12 位 AND DX, 000FH ;清除高 12 位 习题四 4.1 什么是"三种基本结构" 解释"基本"两个字在其中的含义. 答:三种基本结构指:顺序结构,选择结构,循环结构. 使用这 3 种结构,可以编制出任何所需要的程序,因此冠以"基本"结构. 4.2 什么叫做"控制转移指令" 它和数据传送,运算指令有什么区别 它是怎样实现它的功能 的 答:控制转移指令是可以改变指令执行顺序的指令.数据传送,运算指令总是顺序执行的,而控 制转移指令通过改变 IP 和/或 CS 寄存器的值,改变了程序指令的执行顺序. 4.3 指令"JMP DI"和"JMP WORD PTR [DI]"作用有什么不同 请说明. 答:上述两条指令都是段内近转移指令,但是偏移地址的来源不同.指令"JMP DI"执行时,新的 偏移地址在 DI 寄存器内,"JMP WORD PTR [DI]"时,目的偏移地址在存储单元中,该存储单元的 地址在 DS: DI 中. 4.4 什么是"近程"转移 什么是"远程"转移 它们的实现方法有什么不同 答:执行"近程"转移时,转移的目的地与出发地在同一个段内,它们具有相同的段基址.因此,为 了实现"近程"转移,只需要改变 IP 寄存器的值."远程"转移的目的地与出发地不在同一个段,为 了实现这个转移,必须同时改变 CS 和 IP 寄存器的值. 4.5 已知(AX)= 836BH,X 分别取下列值,执行"CMP AX, X"后,标志位 ZF,CF,OF,SF 各是什么 (1)X=3000H (2)X=8000H (3)X=7FFFFH (4)X=0FFFFH (5)X=0 答:上述指令执行后,标志位 ZF,CF,OF,SF 的状态分别是: (1) ZCOS=0010 (2) ZCOS=0000 (3) ZCOS=0010 (4) ZCOS=0101 (5) ZCOS=0001 4.6 已知(AX)= 836BH,X 分别取下列值,执行"TEST AX, X"后,标志位 ZF,CF,OF,SF 各是什么 (1)X=0001H (2)X=8000H (3)X=0007H (4)X=0FFFFH (5)X=0 答:上述指令执行后,标志位 ZF,CF,OF,SF 的状态分别是: (1) ZCOS=0000 (2) ZCOS=0001 (3) ZCOS=0000 (4) ZCOS=0001 (5) ZCOS=1000 4.7 测试名为 X 的一个字节,如果 X 的第 1,3 位均为 1,转移到 L1,如果只有一位为 1,转移到 L2, 如果两位全为 0,转移到 L3.写出对应的指令序列. 答: MOV AL, X AND AL, 0000 1010B JZ L3 CMP AL, 0000 1010B JE L1 JMP L2 4.8 假设 X 和 X+2 字单元存放有双精度数 P,Y 和 Y+2 字单元存放有双精度数 Q,下面程序完成 了什么工作 MOV DX, X+2 MOV AX, X ;双精度数 P 送入 DX, AX ADD AX, X ADC DX, X+2 ;计算 2*P 送入 DX, AX CMP DX, Y+2 ;2P 与 Q 的高位比较

JL L2 ;2PQ,转 L1 (Z=1) CMP AX, Y ;如果高位相等,则比较低位 JBE L2 ;2P 的低位小于等于 Q 的低位,转 L2(Z=2) L1: MOV Z, 1 JMP SHORT EXIT L2: MOV Z, 2 EXIT: …… 答:程序根据 2P 与 Q 的大小,确定 Z 的值. 如果 2P≤Q,则 Z=2 如果 2P>Q, 则 Z=1 请参阅程序注解 4.9 编写指令序列,将 AX 和 BX 中较大的绝对值存入 AX,较小的绝对值存入 BX. 答: AND AX, AX JGE SKIP1 NEG AX SKIP1: AND BX, BX JGE SKIP2 NEG BX SKIP2: CMP AX, BX JGE SKIP3 XCHG AX, BX SKIP3: …… 4.10 编写指令序列,比较 AX,BX 中的数的绝对值,绝对值较大的数存入 AX,绝对值较小的数存 入 BX. 答: PUSH AX PUSH BX AND AX, AX JGE SKIP1 NEG AX SKIP1: AND BX, BX JGE SKIP2 NEG BX SKIP2: CMP AX, BX POP BX POP AX JGE SKIP3 XCHG AX, BX SKIP3: …… 4.11 编写指令序列,如果 AL 寄存器存放的是小写字母,把它转换成大写字母,否则不改变 AL 内容. 答: CMP AL, 'a' JB DONE CMP AL, 'z' JA DONE

SUB AL, 'a'-'A' DONE: …… 4.12 计算分段函数: X 的值从键盘输入,Y 的值送显示器输出. 答: INCLUDE YLIB.H DATA SEGEMNT MESS1 DB 0DH, 0AH, 'Input value of X please : $' MESS2 DB 0DH, 0AH, ' Y= : $' DATA ENDS CODE SEGMENT ASSUME CS: CODE, DS: DATA START: MOV AX, DATA MOV DS, AX LEA DX, MESS1 CALL READINT ;输入 X 的值 CMP AX, -2 JGE L2 L1: SUB AX, 3 ;AX←X-3 JMP DONE L2: CMP AX, 3 JG L3 MOV BX, AX ADD AX, AX ;AX←2X ADD AX, AX ;AX←4X ADD AX, BX ;AX←5X ADD AX, 6 ;AX←5X+6 JMP DONE L3: MOV AX, 2 ;AX←2 DONE: LEA DX, MESS2 CALL WRITEINT ;输出 Y 的值 CALL CRLF MOV AX, 4C00H INT 21H CODE ENDS END START 4.13 计算分段函数: A, B 的值从键盘输入,Y 的值送显示器输出(∧表示"并且",∨表示"或者"). 答: INCLUDE YLIB.H DATA SEGEMNT MESS1 DB 0DH, 0AH, 'Input the value of A please : $' MESS2 DB 0DH, 0AH, 'Input the value of B please : $' MESS3 DB 0DH, 0AH, 'Y= : $'

A DW B DW DATA ENDS CODE SEGMENT ASSUME CS: CODE, DS: DATA START: MOV AX, DATA MOV DS, AX LEA DX, MESS1 CALL READINT ;输入 A MOV A, AX LEA DX, MESS2 CALL READINT ;输入 B MOV B, AX AND AX, AX JL L1 ;B<0,转 L1 CMP A, 0 JL L1 ;A(6-J) I: 6-J . INCLUDE YLIB.H CODE SEGMENT ASSUME CS: CODE START: CALL CRLF MOV SI, 1 ;SI 为行号 ROW: MOV CX, 5 ;CX 为 6-列号 COL: CMP SI, CX ;判断当前位置 JB UP DOWN: MOV AX, CX ;下半三角,取 6-列号 JMP OUTPUT UP: MOV AX, SI ;上半三角,取行号 OUTPUT: MOV DX, -1 CALL WRITEDEC ;输出一个数据 LOOP COL CALL CRLF ;结束本行 INC SI ;修改行号 CMP SI, 5 JBE ROW ;未满 5 行,继续 MOV AX, 4C00H INT 21H CODE ENDS END START 习题五 根据下面条件,画出每次调用子程序或返回时的堆栈状态.

主程序调用 NEAR 属性的 SUB1 子程序,返回的偏移地址为 1200H. 进入 SUB1 后调用 NEAR 属性的 SUB2 子程序,返回的偏移地址为 2200H. 进入 SUB2 后调用 FAR 属性的 SUB3 子程序,返回的段基址为 4000H,偏移地址为 0200H. 从 SUB3 返回 SUB2 后. 从 SUB2 返回 SUB1 后. 从 SUB1 返回主程序后. 解: 编写几个简单的子程序. (1)显示一个字符的子程序.入口参数:DL=字符的 ASCII 码. (2)从键盘上读取一个字符的子程序.出口参数:读取字符的 ASC 码在 CHAR 中. (3)输出换行回车的子程序.无入口,出口参数. 解:(1)SHOW PROC MOV AH, 02H INT 21H RET SHOW ENDP (2)READKEY PROC MOV AH, 01H INT 21H MOV CHAR, AL RET READKEY ENDP (3)CRLF PROC MOV AL, 0AH MOV AH, 02H INT 21H MOV AL, 0DH INT 21H RET CRLF ENDP 过程定义的一般格式是怎样的 子程序入口为什么常有 PUSH 指令 出口为什么有 POP 指令 解:过程的定义格式如下: 过程名 PROC [NEAR/FAR] 程序体 过程名 ENDP 在子程序入口处把相关寄存器的值入栈保护,程序返回前再恢复它们的值,这个操作称为"保 护现场"和"恢复现场",这两种操作分别用 PUSH 指令和 POP 指令实现. . 阅读下面的程序,指出该程序计划完成的功能,同时指出程序中尚存在的错误. CODE SEGMENT ASSUME: CS: CODE START: MOV CX, 20 LOOP0: CALL PRINTSPACE LOOP LOOP0

MOV AH, 4CH INT 21H PRINTSPACE PROC NEAR MOV CX, 40 ;该行上面添加:PUSH CX PSLOOP:MOV AL, ' ' MOV AH, 02H INT 21H LOOP PSLOOP MOV AL, 0AH MOV AH, 02H INT 21H MOV AL, 0DH MOV AH, 02H INT 21H ; 该行下面添加:POP CX RET PRINTSPACE ENDP CODE ENDS END START 功能:输出 20 行空行,每行有 40 个空格. 编写子程序,把 8 位或 16 位二进制数转换成二进制数字串. 入口参数:CX=被转换数的位数,DX=要转换的二进制数(如果 CX=8,那么二进制数在 DL 中),DS: DI=存放二进制数字字符串缓冲区的首地址 出口参数:转换后的二进制数字字符串存放在 DS: DI 指向的缓冲区内. 解: TRANS PROC PUSH DI CMP CX, 8 JE EIGHT NEXT: ROL DX, 1 MOV AL, 18H RCL AL, 1 MOV [DI], AL INC DI LOOP NEXT JMP EXIT EIGHT: ROL DL, 1 MOV AL, 18H RCL AL, 1 MOV [DI], AL INC DI LOOP EIGHT EXIT: POP DI RET TRANS ENDP 阅读下面的子程序,叙述它完成的功能,它的入口参数和出口参数各是什么

CLSCREEN PROC MOV AX, 0600H MOV CX, 0 MOV DH, X MOV DL, Y MOV BH, 07H INT 10H RET CLSCREEN ENDP 解:屏幕窗口上卷,左上角为(0,0),右下角为(y, x),卷入行属性为黑底白字. 编写程序,键入一个以$为结束符的数字串,统计其中"0"~"9"各个数字出现的次数,分别存放 到 S0~S9 这 10 个单元中去. 解:.MODEL SMALL .DATA S0 DB 0 S1 DB S2 DB 0 S3 DB 0 S4 DB 0 S5 DB 0 S6 DB 0 S7 DB 0 S8 DB 0 S9 DB 0 KEYIN DB 100 DUP(0) .CODE START: MOV AX, @DATA MOV DS, AX MOV CX, 0 LEA BX, KEYIN NEXT: MOV AH, 01H INT 21H CMP AL, '$' JZ COUNT INC CX MOV [BX], AL INC BX JMP NEXT COUNT: LEA BX, KEYIN COUNT1:LEA DI, S0 MOV AL, [BX] SUB AL, 30H MOV AH, 0 ADD DI, AX

INC BYTE PTR[DI] INC BX LOOP COUNT1 MOV AX, 4C00H INT 21H END START 下面程序求某数据区中无符号数据最大值,观察程序执行中堆栈变化,画出以下 5 个堆栈状态 图. (1)CALL MAX 指令执行之前 (2)CALL MAX 指令执行之后. (3)保护现场之前 (4)恢复现场之后 (5)执行指令 POP SMAX 之后 程序清单如下: DATA SEGMENT BUF DW 98, 34, 897, 345, 678, 21345, 67, 2 COUNT EQU ($-BUF) / 2 SMAX DW DATA ENDS CODE SEGMENT ASSUME CS: CODE, DS: DATA START: MOV AX, DATA MOV DS, AX LEA AX, BUF ; 入口参数进栈 PUSH AX MOV AX, COUNT PUSH AX CALL MAX POP SMAX ; 最大值出栈,送 SMAX MOV AH, 4CH INT 21H MAX PROC PUSH BP MOV BP, SP MOV SI, [BP+6] ; BUF 的偏移地址送 SI MOV CX, [BP+4] ; COUNT 送 CX MOV BX, [SI] ; 取第一个数据至 BX DEC CX MAX1: ADD SI, 2 CMP BX, [SI] JAE NEXT MOV AX, [SI] ; 取第二个数至 AX NEXT: LOOP MAX1 MOV [BP+6], BX ; 最大值进栈

POP BP RET 2 ; 返回后 SP 指向最大值 MAX ENDP CODE ENDS END START 编写求绝对值的子程序,利用它计算三个变量的绝对值之和. 解:.MODEL SMALL .DATA VALUE DW -5, 5, -10 SUM DW 0 .CODE START: MOV AX, @DATA MOV DS, AX LEA BX, VALUE MOV CX, 3 MOV SUM, 0 ONE: CALL ABS ADD SUM, AX ADD BX, 2 LOOP ONE MOV AX, 4C00H INT 21H ; 子程序 ABS ; 功能:求一个字整数的绝对值 ; 入口:字整数的偏移地址在 BX 中 ; 出口:该字整数的绝对值在 AX 中 ABS PROC MOV SUM, 0 AGAIN: MOV AX, [BX] AND AX, AX JGE SKIP NEG AX SKIP: RET ABS ENDP END START 子程序计算从 2 开始的 N(N<50)个偶数之和(2+4+6+…),主程序从键盘输入整数 N,调用子程序 求出 N 个偶数之和,并显示结果.用以下 3 种方法编写完整程序. 子程序和主程序在同一代码段. 在同一模块(源程序文件),但不在同一代码段. 各自独立成模块,即在不同的源程序文件中. 解:(1) INCLUDE YLIB.H .MODEL SMALL .DATA SUM DW 0

PROMPT1 DB 0DH, 0AH, 'INPUT THE NUMBER N:$' PROMPT2 DB 0DH, 0AH, 'THE SUM IS :$' .CODE START: MOV AX, @DATA MOV DS, AX LEA DX, PROMPT1 CALL READDEC CMP AX, 0 JZ EXIT MOV CX, AX CALL SUMM LEA DX, PROMPT2 CALL WRITEDEC CALL CRLF EXIT: MOV AX, 4C00H INT 21H SUMM PROC MOV AX, 0 NEXT: MOV BX, CX ADD BX, BX ADD AX, BX LOOP NEXT RET SUMM ENDP END START (2) INCLUDE YLIB.H DATA SEGMENT SUM DW 0 PROMPT1 DB 0DH, 0AH, 'INPUT THE NUMBER:$' PROMPT2 DB 0DH, 0AH, 'THE SUM IS:$' DATA ENDS CODE1 SEGMENT ASSUME DS: DATA, CS: CODE1 START: MOV AX, DATA MOV DS, AX LEA DX, PROMPT1 CALL READDEC CMP AX, 0 JZ EXIT MOV CX, AX CALL FAR PTR SUMM LEA DX, PROMPT2 CALL WRITEDEC CALL CRLF

EXIT: MOV AX, 4C00H INT 21H CODE1 ENDS CODE2 SEGMENT ASSUME CS: CODE2, DS: DATA SUMM PROC FAR MOV AX, 0 NEXT: MOV BX, CX ADD BX, BX ADD AX, BX LOOP NEXT RET SUMM ENDP CODE2 ENDS END START ; EXEC5103A.ASM PUBLIC SUMM CODE2 SEGMENT ASSUME CS: CODE2 SUMM PROC FAR MOV AX, 0 NEXT: MOV BX, CX ADD BX, BX ADD AX, BX LOOP NEXT RET SUMM ENDP CODE2 ENDS END ; EXEC5103B.ASM INCLUDE YLIB.H EXTRN SUMM DATA SEGMENT SUM DW 0 PROMPT1 DB 0DH, 0AH, 'INPUT THE NUMBER:$' PROMPT2 DB 0DH, 0AH, 'THE SUM IS:$' DATA ENDS CODE1 SEGMENT ASSUME DS: DATA, CS: CODE1 START: MOV AX, DATA MOV DS, AX LEA DX, PROMPT1 CALL READDEC CMP AX, 0

JZ EXIT MOV CX, AX CALL FAR PTR SUMM LEA DX, PROMPT2 CALL WRITEDEC CALL CRLF EXIT: MOV AX, 4C00H INT 21H CODE1 ENDS END START 从键盘输入一串字符,以$为结束符,存储在 BUF 中.子程序把字符串中的大写字母改成小写字 母,最后由主程序把字符串送显示器输出. 解: .MODEL SMALL .DATA BUF DB 100 DUP ( ) .CODE START: MOV AX, @DATA MOV DS, AX LEA BX, BUF CALL KEYIN CALL CONVERT LEA DX, BUF MOV AH, 09H INT 21H MOV AX, 4C00H INT 21H KEYIN PROC PUSH BX MOV CX, 0 NEXT: MOV AH, 01H INT 21H MOV [BX], AL CMP AL, '$' JZ EXIT INC CX INC BX JMP NEXT EXIT: POP BX RET KEYIN ENDP CONVERT PROC CONVERT1: MOV AL, [BX] CMP AL, 'A'

JB NEXT1 CMP AL, 'Z' JA NEXT1 ADD BYTE PTR [BX], 20H NEXT1: INC BX LOOP CONVERT1 RET CONVERT ENDP END START 从键盘输入一个字符串(长度<80),若该字符串不包括非数字字符,则显示"YES",否显示"NO".设 计一个过程,判断字符串是否为数字串. 解: .386 DATA SEGMENT USE16 STRING DB 80, , 81 DUP( ) YES DB 0DH, 0AH, 'YES. $' NO DB 0DH, 0AH, 'NO. $' DATA ENDS CODE SEGMENT USE16 ASSUME CS: CODE, DS: DATA START: MOV AX, DATA MOV DS, AX MOV AH, 0AH LEA DX, STRING INT 21H MOV CL, STRING+1 MOV CH, 0 MOV SI, 2 CALL EXAM CMP AH, 0 JE NOMESS LEA DX, YES JMP DISP NOMESS: LEA DX, NO DISP: MOV AH, 09H INT 21H MOV AX, 4C00H INT 21H EXAM PROC MOV AH, 1 NEXT: MOV AL, STRING [SI] CMP AL, '0' JB EXIT CMP AL,'9' JA EXIT

INC SI LOOP NEXT JMP EXIT1 EXIT: MOV AH, 0 EXIT1: RET EXAM ENDP CODE ENDS END START 编写程序,判断某年是否是闰年.年份从键盘输入,输出是否是闰年的信息. 判断是闰年的条件是(AX 中为键盘输入的年份): (((AX) MOD 4 = =0) AND ((AX) MOD 100 0)) OR ((AX) MOD 4 = =0) 表达式为真. 解: INCLUDE YLIB.H DATA SEGMENT ; 定义数据段 MESS0 DB 0DH, 0AH, 'PLEASE INPUT A YEAR: $' MESS1 DB 0DH, 0AH, 'THIS IS A LEAP YEAR! $' MESS2 DB 0DH, 0AH, 'THIS IS NOT A LEAP YEAR! $' DATA ENDS CODE SEGMENT ASSUME DS: DATA, CS: CODE START: MOV AX, DATA MOV DS, AX LEA DX, MESS0 CALL READDEC ; 输入年份 CALL IFLEAP JC ISLEAP ; CF=1, 转 ISLEAP LEA DX, MESS2 ; CF=0,输出不是闰年的信息 JMP DISP ISLEAP: LEA DX, MESS1 ; 输出是闰年的信息 DISP: MOV AH, 09H INT 21H MOV AX, 4C00H INT 21H IFLEAP PROC NEAR ; 判断是否闰年子程序 PUSH BX ; 入口:AX=年号 PUSH CX ; 出口:CF=1 表示闰年,CF=0 表示非闰年 PUSH DX MOV CX, AX ; 年号暂存 CX MOV DX, 0 MOV BX, 4 DIV BX CMP DX, 0 JNZ NO ; 不能被 4 整除,转 NO MOV AX, CX

MOV DX, 0 MOV BX, 100 DIV BX CMP DX, 0 JNZ YES ; 能被 4 整除,不能被 100 整除,转 YES MOV AX, CX MOV DX, 0 MOV BX, 400 DIV BX CMP DX, 0 JZ YES ; 能被 400 整除,转 YES NO: CLC ; 不是闰年,CF=0 JMP LEXIT YES: STC ; 是闰年,CF=1 LEXIT: POP DX POP CX POP BX RET IFLEAP ENDP CODE ENDS END START 设计一个子程序,求 N*N 字数组的主对角线之和,并在屏幕上显示出来,数组按行的次序存储. 入口参数:DS: SI=数组首地址,CX=N; 出口参数:AX=主对角线之和; 解: INCLUDE YLIB.H DATA SEGMENT ARRAY DW 1, 2, 3, -1, -2, -3, 5, 6, 7 PROMPT DB 0AH, 0AH, 'THE SUM IS:$' DATA ENDS CODE SEGMENT ASSUME CS: CODE, DS: DATA START: MOV AX, DATA MOV DS, AX LEA SI, ARRAY MOV CX, 3 CALL SUM LEA DX, PROMPT CALL WRITEINT MOV AX, 4C00H INT 21H SUM PROC MOV AX, 0

MOV DX, CX ADD DX, DX MOV BX, 0 NEXT: ADD AX, [BX][SI] ADD BX, DX ADD BX, 2 LOOP NEXT RET SUM ENDP CODE ENDS END START 利用本教材提供的库子程序编写程序,从键盘输入两个带符号十进制数以及一个"+"或"-"运 算符,计算两数的和或差,在屏幕上输出其十进制结果. 解: INCLUDE YLIB.H .MODEL SMALL .DATA MESS1 DB 0AH, 0DH, 'INPUT THE NUMBER: $' MESS2 DB 0AH, 0DH, 'OPERATOR ERROR. $' MESS3 DB 0AH, 0DH, 'THE RESULT IS: $' MESS4 DB 0AH, 0DH, 'INPUT THE OPCODE( + / - ): $' X DW ; 定义参与运算的数 Y DW ; 定义参与运算的数 RESULT DW ; 定义运算结果 OP DB ; 定义参与运算符 .CODE START: MOV AX @DATA MOV DS, AX MOV DX, OFFSET MESS1 ; 设置入口参数 DX=提示字符串首地址 CALL READINT ; 调用读十进制数子程序 MOV X, AX ; 返回参数 AX=十进制数,送 X LEA DX, MESS4 ; 提示输入操作符 MOV AH, 9H INT 21H MOV AH, 01H ; 读入操作符,送 OP INT 21H MOV OP, AL MOV DX, OFFSET MESS1 ; 设置入口参数 DX=提示字符串首地址 CALL READINT ; 调用读十进制数子程序 MOV Y, AX ; 返回参数 AX=十进制数,送 Y CMP OP, '+' ; 判断操作符 JE PLUS ; 转加法运算 CMP OP, '-'

JE MINUS ; 转减法运算 ERROR: LEA DX, MESS2 ; 输出错误信息 MOV AH, 9H INT 21H EXIT: MOV AX, 4C00H ; 返回 DOS INT 21H PLUS: MOV AX, X ; 加法运算 ADD AX, Y JMP DISP ; 转显示 MINUS: MOV AX, X ; 减法运算 SUB AX, Y DISP: MOV RESULT, AX ; 结果送 RESULT LEA DX, MESS3 ; 输出提示信息 CALL WRITEINT ; 调用子程序显示十进制数 JMP EXIT END START 编写完整程序,调用 READINT 子程序,从键盘读入一个带符号整数,以二进制格式输出它的补 码. 解: INCLUDE YLIB.H DATA SEGMENT NUM DW PROMPT1 DB 0DH, 0AH, 'INPUT A NUMBER: $' PROMPT2 DB 0DH, 0AH, 'THE COMPLEMENT IS:$' DATA ENDS CODE SEGMENT ASSUME CS: CODE, DS: DATA START: MOV AX, DATA MOV DS, AX LEA DX, PROMPT1 CALL READINT PUSH AX LEA DX, PROMPT2 MOV AH, 09H INT 21H POP AX CALL DISP CALL CRLF MOV AX, 4C00H INT 21H DISP PROC MOV CX, 16 MOV BX, AX

NEXT: ROL BX, 1 RCL DL, 1 AND DL, 01H OR DL, 30H MOV AH, 02H INT 21H LOOP NEXT RET DISP ENDP CODE ENDS END START 设计一个子程序,求带符号字数组中绝对值最大的数,返回其地址和最大值. 入口参数:DS: SI=数组首地址,CX=元素个数(大于 0); 出口参数:ES: DI=绝对值最大的数所在的地址,AX=绝对值最大的数; 解: MAXABS PROC PUSH CX PUSH SI PUSH DS POP ES XOR AX, AX NEXT: MOV BX, WORD PTR [SI] AND BX, BX JZ OK NEG BX OK: CMP BX, AX JLE SKIP MOV AX, BX MOV DI, SI SKIP: ADD SI, 2 LOOP NEXT POP SI POP CX RET MAXABS ENDP 利用子程序 READINT 和 WRITEINT,编写完整程序,对输入的两个整数比较大小,输出其中大的 一个. 解: INCLUDE YLIB.H DATA SEGMENT NUM DW PROMPT1 DB 0AH, 0DH, 'Input The First Number: $' PROMPT2 DB 0AH, 0DH, 'Input The Second Number: $' PROMPT3 DB 0AH, 0DH, 'The Max Number is: $'

DATA ENDS CODE SEGMENT ASSUME CS: CODE, DS: DATA START: MOV AX, DATA MOV DS, AX LEA DX, PROMPT1 CALL READINT MOV BX, AX LEA DX, PROMPT2 CALL READINT CMP AX, BX JGE DISP MOV AX, BX DISP: LEA DX, PROMPT3 CALL WRITEINT MOV AX, 4C00H INT 21H CODE ENDS END START 编写排序子程序 SORT,以 DS,SI 和 CX 作为入口参数,把 DS:SI 为起始地址的一个带符号的字数 组进行由小到大排序,参数 CX 中存放的是数组中元素个数. 解: DATAREA SEGMENT ARRAY DW 1, 9, 6, 8, 5, 4 CNT DW 6 ADDR DW DATAREA ENDS CODE SEGMENT ASSUME CS: CODE, DS: DATAREA START: MOV AX, DATAREA MOV DS, AX LEA SI, ARRAY MOV CX, CNT CALL SORT MOV AX, 4C00H INT 21H SORT PROC PUSH CX PUSH AX PUSH BX PUSH SI INIT: MOV BX, 1 DEC CX JZ SORTED

PUSH SI PUSH CX NEXT: MOV AX, [SI] CMP [SI+2], AX JGE CONT XCHG [SI+2], AX MOV [SI], AX XOR BX, BX ; 置交换标志 CONT: ADD SI, 2 LOOP NEXT POP SI POP CX CMP BX, 0 JE INIT SORTED: POP SI POP BX POP AX POP CX RET SORT ENDP CODE ENDS END START 编写一个子程序,以 AX 为入口参数,把 AX 中的各个二进制位颠倒次序后还放回 AX 中.例如, 入口参数 AX=1011000111101001B,处理后 AX 应为 1001011110001101B. 解: INVERT PROC PUSH CX PUSH BX MOV CX, 16 NEXT: ROL AX, 1 RCR BX, 1 LOOP NEXT MOV AX, BX POP BX POP CX RET INVERT ENDP 编写子程序,入口参数是一个字数据,存放在 AX 中,统计该字的 16 个二进制位中含有多少个 1 和多少个 0. 解: DATA SEGMENT NUM DW 1234H

ZERO DB 0 ONE DB 0 DATA ENDS CODE SEGMENT ASSUME DS: DATA, CS: CODE START: MOV AX, DATA MOV DS, AX MOV AX, NUM MOV CX, 16 CALL COUNT MOV ONE, AL MOV ZERO, AH MOV AX, 4C00H INT 21H COUNT PROC PUSH BX MOV BX, 0 NEXT: ROL AX, 1 ADC BX, 0 LOOP NEXT MOV BH, 16 SUB BH, BL MOV AX, BX POP BX RET COUNT ENDP CODE ENDS END START 用 C 语言编写主程序,定义一个一维数组 ARRAY,调用汇编子程序 MAX 求数组中的最大值. 解:C 语言程序如下(C 语言设置模式为"large") int far max( int far*, int ); int array[10]={ 1, 3, 5, 89, 976, 56, 34, -5, 0, 12 }; main() { int n; n=max(array, 10); printf("The biggest number in array is %d\n", n); } 汇编语言程序如下 .MODEL LARGE PUBLIC _MAX .CODE _MAX PROC FAR

PUSH BP MOV BP, SP PUSH DS LDS SI, [BP+6] MOV CX, [BP+10] MOV AX, [SI] LOP: JCXZ DONE CMP AX, [SI] JGE BIG_EQU MOV AX, [SI] BIG_EQU: INC SI INC SI DEC CX JMP LOP DONE: POP DS POP BP RET _MAX ENDP END 用 C 语言主程序调用汇编子程序,完成两个变量的减法 Z=X-Y,要求采用堆栈传递参数,画出堆 栈传递参数的示意图. 解: C 语言程序如下(C 语言设置模式为"small") extern int minus(int, int); main() {int x = 200, y= 300; int z ; printf("\n z=%d\n", minus(x, y); } 汇编语言程序如下 .MODEL SMALL PUBLIC _MINUS .CODE _MINUS PROC NEAR PUSH BP MOV BP, SP MOV AX, [BP+4] SUB AX, [BP+6] POP BP RET _MINUS ENDP END

编写一段递归子程序计算 N!(N>=0).其递归定义如下: 0!=1 N! =N * (N-1)! (N>0) 解: .DATA N DW 5 M DD .CODE START: MOV AX, @DATA MOV DS, AX MOV CX, N CALL FACT MOV WORD PTR M, AX MOV WORD PTR M+2, DX MOV AX, 4C00H INT 21H FACT PROC NEAR CMP CX, 0 JZ DONE PUSH CX DEC CX CALL FACT POP CX MUL CX JMP EXIT DONE: MOV AX, 1 EXIT: RET FACT ENDP END START 习题六 使用串操作指令,在 STRING 字符串中查找有无字符'A',如有将标志 flag 置 1,否则将 flag 清 0. 答:程序如下: .model small .data string db 'All students $' flag db 0 .code start: mov ax, @data mov es, ax lea di, string mov cx, flag-string mov al, 'A' cld repnz scasb

jz yes mov flag, 0 jmp exit yes: mov flag, 1 exit: mov ax, 4c00h int 21h end start 使用串操作指令从左到右把字符串 STRING1 中的字符送到 STRING2 中. 答:程序如下: data segment string1 db 'This is an example. ' string2 db 40 dup( ) data ends code segment assume cs: code, ds: data, es: data start: mov ax, data mov ds, ax mov es, ax lea si, string1 lea di, string2 mov cx, string2-string1 cld rep movsb mov ax, 4c00h int 21h code ends end start 使用串操作指令从右到左把字符串 STRING1 中的字符送到 STRING2 中. 答:程序如下: data segment string1 db 'This is an example. ' string2 db 40 dup( ) data ends code segment assume cs: code, ds: data, es: data start: mov ax, data mov ds, ax mov es, ax lea si, string1 lea di, string2 mov cx, string2-string1 add si, cx

add di, cx std rep movsb mov ax, 4c00h int 21h code ends end start 在 STRING 中查找空格,记下最后一个空格的位置,存放在变量 SPACE 中.如果没有空格,置 SPACE 为-1. 答:程序如下: .model small .data string db 'This is an example $' space dw 0 .code start: mov ax, @data mov ds, ax mov space, -1 lea si, string cld aga: lodsb cmp al, '$' je okend cmp al, ' ' jnz next mov space, si dec space next: jmp aga okend: mov ax, 4c00h int 21h end start 两个字符串 str1 与 str2 以"$"字符结束,比较它们的字符是否相同,如果相同,在屏幕上显示 "Yes.",否则显示"No.". 答:程序如下: .model small .data string1 db 'all students$' string2 db 'all stodents$' mess1 db 'yes.$' mess2 db 'no.$' .code start: mov ax, @data mov ds, ax mov es, ax

lea si, string1 lea di, string2 cld aga: lodsb scasb jne nots cmp al, '$' jne aga yes: lea dx, mess1 jmp exit nots: lea dx, mess2 exit: mov ah, 09h int 21h mov ax, 4c00h int 21h end start 什么是文件 什么是文件代号 答:文件是存放在外存储器上的程序或数据.需要长期保存的程序和数据必须以"文件"的形式, 存放在外存储器上. 对一个磁盘文件进行操作时,该文件从"静止"状态转变为"活动"状态,称为"打开".操作系统为 每个处于"活动"状态的文件分配一个用 16 位二进制表示的"文件代号"(Handle).在此后的文 件操作中,文件代号代表这个已经打开并正在进行读,写等操作的文件. 如何用文件代号方式来建立文件 打开文件 关闭文件 答:对磁盘文件的处理都是使用 DOS 或 BIOS 的功能调用来实现的.BIOS 功能调用(中断服务 INT 13H)实现最底层的文件操作,它需要给出文件在磁盘上的物理地址.DOS 中断服务(INT 21H)能 实现高级的文件操作,只要给出文件名就能读写文件. 对于一个磁盘上不存在的文件,使用之前首先要"建立"这个文件.使用功能号为 3CH 的 DOS 功 能调用来建立一个文件. 对一个已经存在的磁盘文件进行读,写操作前,首先要"打开"这个文件.使用功能号为 3DH 的 DOS 功能调用打开一个文件时,除了将 ASCIZ 串首地址装入 DS: DX 之外,还要将一个"文件存取 代码"置入 AL 寄存器. 一个文件读写完毕之后,需要将它关闭,这个文件从"活动状态"回复到"静止"状态.关闭文件的 操作通过 3EH 的 DOS 功能调用实现. 文件属性指的是什么 答:每个文件都有一个记录该文件特性的字节,称为文件属性.该字节各位所代表的含义如下: D0——只读文件,该文件不能进行写操作 D1——隐藏文件,用 DIR 查不到该文件 D2——系统文件,用 DIR 查不到该文件 D3——软盘的卷标号,该文件内容为磁盘的"卷标" D4——子目录,该文件内容为下一级文件的"目录" D5——归档位,已写入并关闭了的文件(硬盘用) 编写程序,建立一个名为 File1.txt 的文件,建立成功则在屏幕上显示"SUCCESS",否则显示 "ERROR"信息. 答:参照例 6-4

打开文件操作时,先要在 AL 中设置文件存取代码,其作用是什么 答:存取代码告诉操作系统打开文件要进行什么样操作.常用的文件存取代码是: 0:为读而打开文件 1:为写而打开文件 2:为读和写打开文件 只读文件只能用代码 0 来打开,如果使用存取代码 1 或 2 时将报告错误.打开一个不存在的文 件同样也会报告错误. 习题七 7.1 宏指令与子程序有什么不同之处 答:宏指令实际上就代表了它对应的一组指令.对程序中出现的宏指令进行汇编时,这条宏指 令被它对应的一组指令所代替.如果程序中多次使用宏指令,就等于多次重复拷贝了这个指令 组,占用的内存随之增加. 调用子程序通过执行 CALL 指令实现,存在"主程序"与"子程序"之间的两次控制转移.使用宏指 令不存在控制转移的过程. 使用子程序和宏指令都可以提高编程效率.子程序占用固定大小的存储空间,被主程序调用时, 空间不会随调用次数而增加.但是,宏指令占用存储空间会随着使用次数的增加而增加. 7.2 设有一个宏定义如下: DISP MACRO STRING LEA DX, STRING MOV AH, 09H INT 21H ENDM 该宏的功能是什么 参数 STRING 应是什么类型数据 答:该宏的功能是显示一串字符串,参数 STRING 应为字符串的首地址. 7.3 下面是一个软件延时 DELAY 的宏定义,请判断宏是否正确,如果不正确,请改正. 解:该宏使用的标号 D1 应定义为"局部标号",修改后的宏定义如下. DELAY MACRO TIMER LOCAL D1 PUSHA MOV DX, TIMER D1: MOV CX, 0 LOOP $ DEC DX JNZ D1 POPA ENDM 7.4 调用一个宏,将一个'0'~'F'的 ASCII 码转换成 16 进制数,并利用这个宏,将内存中 BUF 开始 的 10 个十六进制数字的 ASCII 码转换为对应的 16 进制数存回 BUF 原来位置. 解: HEX MACRO LOCAL NG_9 CMP AL,'9' JNA NG_9 SUB AL, 7H

NG_9:SUB AL, 30H ENDM .MODEL SMALL .DATA BUF DB '12349845FBD8AE07' .CODE START: MOV AX, @DATA MOV DS, AX MOV BX, 0 MOV CX, 16 NEXT: MOV AL, BUF[BX] HEX MOV BUF[BX], AL INC BX LOOP NEXT MOV AX, 4C00H INT 21H END START 7.5 在 25×80 的文本显示方式下,屏幕上第 8 行第 20 列字符所对应的显存地址是多少 解:偏移地址=页起始偏移地址+2×(字符行坐标×每行列数+列坐标) =0+2×(8×80+20) =528H 7.6 在屏幕中央建立一个 10 行×40 列的窗口,以蓝色为背景,在窗口显示"GOOD DONE!" 解:. MODEL SMALL SCROLL MACRO TOP, LEFT, BOTTOM, RIGHT, ATTRIB MOV AX, 0600H ; 屏幕上卷功能 MOV CH, TOP ; 左上角行号 MOV CL, LEFT ; 左上角列号 MOV DH, BOTTOM ; 右下角行号 MOV DL, RIGHT ; 右下角列号 MOV BH, ATTRIB ; 卷入行属性 INT 10H ; 对指定范围屏幕清屏 ENDM CLS MACRO SCROLL 0, 0, 24, 79, 7 ; 清屏宏定义 ENDM SETCUSOR MACRO PAGE1, ROW, COLUMN MOV AH, 2 ; 设置光标位置宏定义 MOV DH, ROW MOV DL, COLUMN MOV BH, PAGE1 INT 10H

ENDM . DATA MESS1 DB ' GOOD DONE! $' MESS2 DB ' Press Any Key To Exit! $' . CODE START: MOV AX, @DATA MOV DS, AX CLS ;宏指令,清屏 SCROLL 5, 20, 15, 60, 00011111B ;宏指令,清屏,同时建立一个窗口 ;滚屏,在屏幕上建立一个蓝底白字的小窗口 SETCUSOR 0, 8, 30 ;设置光标位置,坐标(8,30) LEA DX, MESS1 ;DOS 调用,在光标位置显示 MESS 字符串 MOV AH, 09H INT 21H SETCUSOR 0, 20, 10 ; 重新设置光标位置 LEA DX, MESS2 ; 显示操作提示字符串 MOV AH, 09H INT 21H MOV AH, 10H ; 等待键盘输入 INT 16H MOV AX, 4C00H INT 21H END START 7.7 INT 10H 的哪个功能能在屏幕上显示一个像素点 答:AH=0CH,写像素. 入口参数:AL=像素值,BH=显示页,CX=X 坐标,DX=Y 坐标 返回参数:无 7.8 在使用 INT 10H 绘制像素点时,在 AL,BH,CX 和 DX 寄存器中需要放置什么值 答:见上题 7.9 写汇编语言程序,将显示模式设置为模式 12H. 解: MOV AH, 0 MOV AL, 12H INT 10H 7.10 在屏幕上用 BIOS 调用,以图形方式画一个正方形,4 条边的颜色不一样. 解: INCLUDE YLIB.H ; 头文件,包含 SETMODE, WRITEPIXEL 宏定义 .MODEL SMALL .DATA OLDMODE DB X DW 100 Y DW 100 COLOR DB 5 LEN EQU 100 .CODE

START: MOV AX, @DATA MOV DS, AX MOV AH, 0FH INT 10H MOV OLDMODE, AL SETMODE 12H MOV CX, LEN MOV DX, Y L1: PUSH CX ; 宏指令 WRITE_PIXEL 会改变 CX 的值,保护 WRITE_PIXEL 0, Y, X, COLOR INC Y POP CX LOOP L1 INC COLOR MOV CX, LEN L2: PUSH CX WRITE_PIXEL 0, Y, X, COLOR INC X POP CX LOOP L2 INC COLOR MOV CX, LEN L3: PUSH CX WRITE_PIXEL 0, Y, X, COLOR DEC Y POP CX LOOP L3 INC COLOR MOV CX, LEN L4: PUSH CX WRITE_PIXEL 0, Y, X, COLOR DEC X POP CX LOOP L4 MOV AH, 0 ; 等待键盘输入 INT 16H MOV AH, 0 ; 恢复原来显示模式 MOV AL, OLDMODE INT 10H MOV AX, 4C00H INT 21H END START 习题八

什么是接口 它在 CPU 与外设之间起什么作用 答:接口是连接计算机"主机"和外部设备的电路,它的一端通过总线与 CPU 相连接,另一端与外 部设备连接.接口电路在 CPU 与外部设备之间对输入/输出的信息进行缓冲,协调外部设备与 CPU 的速度差异.进行信号电平,信号格式的转换,满足两方面对信号的要求. CPU 与 I/O 端口之间传送的信号有哪几种 它们各自的作用是什么 答:CPU 与接口之间传送三种类型的信号. (1)数据信号 数据信号就是 I/O 设备与 CPU 之间要交换的信息,是 I/O 端口与 CPU 之间传送的主要信息. (2)状态信号 状态信号反映外部设备或接口当前的工作状态.CPU 通过读取接口内存储的状态信号来判断 接口或外设的工作状态. (3)控制信号 控制信号用来控制输入/输出的进行,如设置外设/接口的工作方式,控制接口/外设的启动,停 止等. CPU 与外设之间输入/输出方式一般有几种 它们各自的优缺点是什么 答:CPU 与外设之间输入/输出方式主要有: 无条件输入/输出方式:这种方式接口电路最简单,程序最简单,但适用范围受限制. 查询式输入/输出方式:适合于较多的外部设备,但是 CPU 与外部设备"串行"工作,能够同时管 理的外部设备数量少,CPU 使用效率低. 中断控制输入/输出方式:适用于大多数的中,低速外部设备,CPU 可以同时管理多台外部设备, 可以实时响应外部设备的请求,CPU 与外部设备"并行"工作,工作效率高. DMA 传输方式:适合于高速,大数据流量的外部设备,需要专用的控制器,数据传输速度快,CPU 负担轻. 哪几种类型的 I/O 端口 它们的作用是什么 答:根据端口内存放信息的种类,有以下四种端口: 数据输入端口:存放输入设备输入的数据信息,如键盘输入的字符代码. 数据输出端口:存放送往输出设备,准备输出的数据信息,如送往打印机的字符代码. 状态端口(输入):存放外部设备/接口的状态信号,供 CPU 读取. 控制端口(输出):存放 CPU 发往外设的命令/控制信息. 什么是中断,中断源 简单叙述采用中断方式输出数据的全过程 答:由于某种事件的发生,使 CPU 中断(暂时停止)正在执行的程序而转去执行该事件的处理程 序,为该事件服务结束后,继续执行原来被中断的程序,这个过程称为中断. 引起中断的事件称为中断源. 采用中断方式输出数据的过程如下: CPU 向输出设备发出控制命令,启动该设备; 输出设备启动完成,向 CPU 申请中断; CPU 执行中断服务程序,向该设备输出数据; 输出设备执行输出操作,完成后向 CPU 再次发出中断; 重复步骤(3),(4),直到所有数据输出完成. 8086/8088 的中断源分为几类 什么是可屏蔽中断和不可屏蔽中断 答:按照中断源所在的位置,中断可以划分为外部中断和内部中断两大类. 内部中断: (1)中断指令 INT 引起的中断(软件中断). (2)由于 CPU 的某些错误引起的中断,如除法错中断,溢出中断(异常中断).

(3)为调试程序设置的中断(陷阱中断). 外部中断: (1)不可屏蔽中断(NMI),通常代表 CPU 外部的故障,例如存储器校验错. (2)外设完成数据准备,请求进行数据传输引起的可屏蔽中断. 从 CPU 的 INTR 引脚引入的外部中断称为可屏蔽中断,CPU 内 IF=0 时,CPU 不响应这类中断.NMI 引脚引入的外部中断不能够被 IF 位屏蔽,称为不可屏蔽中断. 什么是中断向量及中断向量表 如何设置中断向量表 答:每种类型的中断都有一个相应的中断服务程序来进行处理,中断服务程序的入口地址称为 "中断向量".为了便于管理,80x86 微机系统中把 256 个中断向量按照它们中断类型的顺序组 织成一张表,存放在内存最低的 1KB 中,地址范围 000H~3FFH,这张表称为"中断向量表". 设置中断向量就是把中断服务程序的入口地址放入中断向量表中.设置中断向量有两种方法: (1)用 MOV 指令将中断向量直接写入中断向量表中,称为直接写入法; (2)使用 DOS 功能调用 25H 用来设置中断向量,入口参数为: AH=25H AL=中断类型号 DS: DX=中断向量 8086/8088 的中断服务程序入口地址是如何得到的 答:8086/8088 的中断服务程序入口地址根据该中断的中断类型查"中断向量表"获得. 中断向量表中每四个字节存放一个中断向量,高地址的两个字节存放中断处理程序入口的段 基址(16 位),低地址两个字节存放中断处理程序入口的偏移地址(16 位).因此,每个中断向量在 中断向量表中的存放位置可由中断类型号乘以 4 算出. 某输出设备接口内的数据输出端口地址 210H,状态端口地址为 212H.状态端口的 D7 位代表了 外设的工作状态,D7=1 表示外设忙,D7=0 表示外设空闲.编写一个查询式输出的程序,把数据段 中 LIST 开始的 100 个字节数据向该设备输出. 答:程序如下: .MODEL SMALL .DATA LIST DB 100 DUP( ) ;100 个待输出数据 . CODE START: MOV AX, @DATA MOV DS, AX ; 装载 DS LEA SI, LIST ; 装载输出缓冲区指针 MOV CX, 100 ; 装载计数器初值 AGAIN: MOV DX, 212H IN AL, DX ; 读状态端口 TEST AL, 80H ; 测试 D7 位("忙"位) JNZ AGAIN ; 输出设备"忙"则等待 MOV DX, 210H ; 数据端口地址装入 DX MOV AL, [SI] ; 取待输出数据 OUT DX, AL ; 向数据端口输出 INC SI ; 修改输出缓冲区指针 LOOP AGAIN ; 循环控制 OVER: MOV AX, 4C00H INT 21H

END START 中断类型号为 17H 的中断处理程序的入口地址为 1000H:0760H,写出该中断向量在中断向量 表中的存放位置及存放情况. 答:中断类型号为 17H 的中断向量在中断向量表中的存放位置及存放情况: 中断类型为 1CH 的中断服务程序的入口地址为 INT_SERVE,编写程序把该中断服务程序的入 口地址写入对应的中断向量表中. 答:使用 DOS 功能调用设置中断向量. ┆ PUSH DS MOV AX, SEG INT_SERVE MOV DS, AX MOV DX, OFFSET INT_SERVE MOV AL, 1CH MOV AH, 25H INT 21H POP DS ┆ 8088 微机系统中,从外部中断请求到中断处理,哪些寄存器由系统自动保护 哪些寄存器必须 由用户在中断服务程序中保护 80X86 的中断返回指令 IRET 与子程序返回指令 RET 有什么不 同 答:为了中断服务程序执行结束后能继续执行原来被中断的程序,CPU 把 FLAGS,CS,IP 顺序压入 堆栈保存.中断服务程序结束时,执行 IRET 指令,把保存在堆栈中的 FLAGS,CS,IP 原来值弹出送 回原来的寄存器.用户在中断服务程序中要保护程序中使用到的寄存器.80X86 的中断返回指 令 IRET 与子程序返回指令 RET 主要区别在于 IRET 把保存在堆栈中的 FLAGS,CS,IP 原来值弹出 送回原来的寄存器,而 RET 只把 CS(仅远程子程序),IP 原来值弹出送回原来的寄存器. 打印机接口内数据端口地址为 Data_Port,状态端口地址为 State_Port.打印机收到一个数据后, 状态端口 D7 位变高,阻止送入新的数据.一个数据打印完后,状态端口 D7 位自动变低,CPU 可 以送下一个数据.编写一个程序,用查询方式将内存中从 STRING 开始的一个字符串输出到打 印机,字符串以$为结束标志. 答:可以编制程序如下: .MODEL SMALL .DATA STRING DB "A String for output . $" .CODE START: MOV AX, @DATA MOV DS, AX ; 装载 DS LEA SI, STRING ; 装载输出缓冲区指针 AGAIN: CMP BYTE PTR[SI], '$' JE DONE WAIT1: MOV DX, State_Port IN AL, DX ; 读状态端口 TEST AL, 80H ; 测试 D7 位("忙"位) JNZ WAIT1 ; 打印机"忙"则等待 MOV DX, Data_Port ; 数据端口地址装入 DX

MOV AL, [SI] ; 取待输出字符代码 OUT DX, AL ; 字符代码向数据端口输出 INC SI ; 修改输出缓冲区指针 JMP AGAIN ; 循环控制 DONE: MOV AX, 4C00H INT 21H END START 如果把状态口的 D7 位作为中断请求信号,中断类型设定为 80H,编写采用中断方式输出上述 字符串的程序(包括主程序和中断服务程序). 答:主程序中要设置好中断向量,在数据区,用一个字单元保存指向输出数据的指针 POINTER, 程序如下: ┆ PUSH DS MOV AX, SEG SERVE MOV DS, AX MOV DX, OFFSET SERVE MOV AL, 80H MOV AH, 25H INT 21H POP DS LEA AX, STRING MOV POINTER, AX ┆ 中断服务程序如下: SERVE: PUSH AX PUSH DX PUSH SI PUSH DS MOV AX, DATA MOV DS, AX ; 重新装载数据段段基址 MOV SI, POINTER ; 取出指向输出数据的指针 CMP BYTE PTR[SI], '$' JE OVER ; 数据输出完成,本次不再输出 MOV DX, Data_Port ; 数据端口地址装入 DX MOV AL, [SI] ; 取待输出字符代码 OUT DX, AL ; 字符代码向数据端口输出 INC SI ; 修改输出缓冲区指针 MOV POINTER,SI ;保存指向输出数据的指针 OVER: MOV AL, 20H OUT 20H, AL ; 发送中断结束命令 POP DS POP SI POP DX POP AX

IRET 编写程序,利用系统提供的 55ms 定时中断(类型号 1CH),在显示器的右上角显示当前时间的时: 分:秒值. 答:参照[例 8-5]. 什么是驻留程序 如何实现程序驻留 驻留程序的基本结构如何 答:(1)在计算机系统中,有一类特殊的程序,它们常驻内存,所占用的内存空间受到 DOS 的保护, 不会被后来装入的程序覆盖.它们平时处于"待命"状态,使用者感觉不到它的存在,一旦某个 条件被满足,这个程序被激活,进入"运行"状态,这样的程序称为"驻留程序"(简称 TSR 程序). (2)使用 AH=31H 的 DOS 功能调用可以实现程序的驻留. 入口参数:AH= 31H DX=驻留程序的大小(以"节"为单位,1 节等于 16 个字节) 设置好入口参数,执行 INT 21H 指令,控制权交还 DOS,同时,指定的内存区域处于 DOS 的保护之 下. (3)驻留程序由两部分组成:驻留程序部分,初始化及驻留控制部分.由于 DOS 保护的内存区域 从低地址开始向高地址端延伸,所以应把驻留程序写在程序的头部,初始化及驻留控制程序写 在程序的尾部.驻留程序的一般格式为: CODE SEGMENT ASSUME CS:CODE,DS:CODE ; 驻留程序数据区 …… ; 待驻留的程序 …… MAIN: …… ;准备工作,如装载中断向量表 LEA DX, MAIN ;取驻留程序字节数 MOV CL, 4 SHR DX, CL ;转换成"节"数 MOV AH, 31H ;驻留退出功能号 INT 21H ;驻留并退出 CODE ENDS END MAIN 用.COM 格式编写程序,从键盘输入若干个字数据,求出其中的最大值并输出.输入数据 0 表示 输入结束. 答:可以编制程序如下: INCLUDE YLIB.H CODE SEGMENT ASSUME CS: CODE, DS: CODE ORG 100H START: JMP BEGIN MESS1 DB 0AH, 0DH, "Input A Number Please: $" MESS2 DB 0AH, 0DH, "The Maxminum Is $" BEGIN: PUSH CS POP DS LEA DX, MESS1

CALL READINT CMP AX, 0 JE DONE MOV BX, AX ONE: LEA DX, MESS1 CALL READINT CMP AX, 0 JE OUTPUT CMP AX, BX JGE SKIP MOV BX, AX SKIP: JMP ONE OUTPUT: MOV AX, BX LEA DX, MESS2 CALL WRITEINT CALL CRLF DONE: MOV AX, 4C00H INT 21H CODE ENDS END START SP 1200H CALL SUB1 SP 2200H 1200H CALL SUB2 SP 0200H 4000H 2200H 1200H CALL FAR PTR SUB3 0200H 4000H 2200H 1200H SP 从 SUB1 返回主程序后

0200H 4000H 2200H SP 1200H 从 SUB2 返回 SUB1 后 0200H 4000H SP 2200H 1200H 从 SUB3 返回 SUB2 后. SP 返回偏移地址 COUNT BUF 的偏移地址 CALL MAX 执行之后 SP COUNT BUF 的偏移地址 CALL MAX 执行之前 BP SP 返回偏移地址 COUNT 最大值 恢复现场之后 SP 返回偏移地址 COUNT BUF 的偏移地址 保护现场之前 BP 返回偏移地址 COUNT SP 最大值 执行 RET 2 之后 进入_MINUS 子程序后 的堆栈


更多搜索:汇编答案
推荐相关:
网站首页 | 网站地图
All rights reserved Powered by 大学生考试网 9299.net
文档资料库内容来自网络,如有侵犯请联系客服。zhit325@qq.com