《汇编语言》习题参考答案

1. 课程简介

本课程基于《汇编语言(第 2 版)》郑晓薇 编著,机械工业出版社,可以配合该教材使用。本课程由郑晓薇授权制作,提取教材中的实例以及实验内容,可以在实验楼环境中完成所有实例及实验。实验课程制作符合教材原版实例驱动教学以及实验训练贯穿始终的特点。

本教材可在 当当网 购买(点击链接即可进入购买页面)。

本课程实验列表中的最后模块(本节)为配套教材的习题参考答案,可供读者学习参考。

2. 习题参考答案

汇编语言是一门理论与实践相结合的课程,只有在大量的习题练习和编程训练下,才能很好地掌握基础理论与编程技巧。

本书在编写时采用实例与图示结合的方法使读者能够清楚、直观地看到程序的运行过程,便于更好地理解和掌握汇编语言。在每章内容之后都有相应的实验部分,旨在全面提升读者的综合应用能力和动手操作能力。每章之后的习题强调学习过程中的复习与练习,以加强读者对相关概念的学习与吸收。

本节给出教材各主要章节大部分习题的参考答案,供读者学习使用。

习题一答案

  • 1.1

无符号数: 11010011=211=D3H,01110111=119=77H,10000011=131=83H,00101111=47=2FH,10101010=170=AAH

带符号数:11010011= -45=D3H,01110111=+119=77H,10000011= -125=83H,00101111=+47=2FH,10101010= -86=AAH

  • 1.2

5E8AH,0BE6H,3DEH,4940H

  • 1.3

00011101+00110101=01010010=52H=82, 01001001+11101000=00110001=31H=49, 10111110+01010010=00010000=10H=16, 10011010+11110001=10001011=8BH= -117

  • 1.4

00101001+01010011=01111100+00000110=10000010=82H=82, 01110011-00100100=01001111-00000110=01001001=49H=49, 01100110+00011000=01111110+00000110=10000100=84H=84, 0000000100110010+01110101=0000000110100111+00000110 =0000001000000111=0207H=207

  • 1.5

000020A3H,FF94H,00003456H,007FH,FFFFEC00H

  • 1.6

无符号数:0~65535,0000H~FFFFH;带符号数:-32768~+32767,8000H~7FFFH

  • 1.7

(1) 38H 等于十进制数 56,是十进制数 56 的补码,数字 8 的 ASCII 码,十进制数 38 的压缩 BCD 码

(2) FFH 等于十进制数 -1,是带符号数 -1 的补码,无符号数为 255

(3) 5AH 等于十进制数 90,是十进制数 90 的补码,大写字母 Z 的 ASCII 码

(4) 0DH 等于十进制数 13,是十进制数 13 的补码,回车符的 ASCII 码

  • 1.8

(1) 108=01101100B=6CH,补码 01101100B,压缩 BCD 码 0000000100001000,ASCII 码 313038H

(2) 46=00101110B=2EH,补码 00101110B,压缩 BCD 码 01000110,ASCII 码 3436H

(3) –15=11110001B=F1H,补码 11110001B,ASCII 码 2D3135H

(4) 254=0000000011111110B=00FEH,补码 0000000011111110B,压缩 BCD 码 0000001001010100,ASCII 码 323534H

  • 1.9

(1) 56+63=01110111B,CF=0,SF=0,ZF=0,OF=0 (2) 83-45=00100110B,CF=0,SF=0,ZF=0,OF=0 (3) -74+29=11010011B,CF=0,SF=1,ZF=0,OF=0 (4) -92-37=01111111B,CF=1,SF=0,ZF=0,OF=1

  • 1.10

回车、换行、响铃、ESC 键、空格键、@、P、p

习题二答案

  • 2.9

最少划分为 16 个逻辑段,最多划分为 65536 个逻辑段(每段 16 个字节)

  • 2.10

CS:IP,DS:BX、SI、DI,ES:BX、SI、DI,SS:SP、BP

  • 2.11

字节单元保存 8 位数,字单元保存 16 位数。根据源操作数的属性确定要访问的是字节单元还是字单元。

  • 2.12

对于字节单元来说,偶地址和奇地址一样;对于字单元而言,最好用偶地址保存,可减少 CPU 的访存次数。

  • 2.13

首单元的物理地址=38AE8H,末单元的物理地址=38AE8H+7FFFH=40AE7H

  • 2.16

(1)物理地址=27679H

(2) 物理地址=20F92H

(3) 物理地址=20F92H

(2)和(3)的物理地址是一样的。说明逻辑地址不唯一,多个逻辑地址可对应到同一个物理单元上。

  • 2.17

代码段 CS:IP 的物理地址=55A84H,堆栈段 SS:SP 的物理地址=4DB65H,数据段 DS:BX 的物理地址=17678H,附加段 ES:DI 的物理地址=2BA41H

  • 2.18

当前栈指针所指单元的物理地址是 1522CH。堆栈区中还能保存 254 个字。

  • 2.19

执行 E 200

  • 2.20

执行 U 100

  • 2.21

执行 R CX,然后输入 100

  • 2.22

执行 E DS:0 ‘a’ ‘b’ ‘c’ ‘d’

习题三答案

  • 3.3
MOV AX,BX            ;源操作数为寄存器寻址,EA 无,物理地址 无
MOV AX,1290H        ;立即寻址,EA 无,物理地址 无
MOV AX,[BX]        ;寄存器间接寻址,EA=1290H, 物理地址=2FBB0H
MOV AX,DS:[1290H]    ;直接寻址,EA=1290H, 物理地址=2FBB0H
MOV AX,[BP]        ;寄存器间接寻址,EA=6756H, 物理地址=26A56H
MOV [DI][BX],AX  ;目的操作数为基址变址寻址,EA=3C06H, 物理地址=32526H
MOV ES:[SI],AX        ;寄存器间接寻址,EA=348AH, 物理地址=50CAAH
  • 3.7
MOV AX,[CX]        ;错。CX不能为间址寄存器
MOV AL,1200H        ;错。立即数超出8位寄存器范围
MOV AL,BX            ;错。两个操作数不匹配
MOV [SI][DI],AX        ;错。两个变址寄存器不能在一起
MOV ES:[DX],CX        ;错。DX不能为间址寄存器
MOV [AX],VALUE    ;错。AX不能为间址寄存器
MOV COUNT,[SI]        ;错。两个操作数不能都是存储单元
  • 3.8
;(1) 
MOV AX,BX            

;(2) 
MOV CL,15            

;(3) 
ADD AX,[BX]        

;(4) 
MOV [BX+SI],AL        

;(5) 
MOV AX,VALUE[SI]    

;(6) 
SUB AX,DS:[2000H]
  • 3.9
;(1) 
ADD AX,[X+3]          

;(2) 
MOV BX,3            

;(3) 
MOV BX,3
MOV Y,AX
ADD AX,X[BX]
MOV SI,OFFSET X
MOV Y,AX               
ADD AX,[BX+SI]
MOV Y,AX
  • 3.10

立即寻址方式中操作数(立即数)和指令一起存放在代码段中。

习题四答案

  • 4.10
;(1)  
DATA SEGMENT
    X DW 0
    Y DW 0
DATA ENDS
           
;(2) 
STRING DB ’Computer’

;(3) 
COUNT DB 100 DUP(?)

;(4) 
PI EQU 3.14

;(5) 
VALUE LABEL BYTE
  • 4.11

(1)对。

(2)错。260 超出了字节范围。

(3)错。X3 是字节型,1234H 是字型,不匹配。

(4)对。

(5)错。缺少 DUP。

(6)对。

  • 4.12

(1)AL=3。

(2)AX=2103H。

(3)DX=TABLE 的偏移地址。

(4)CL=33H

(5)BX=TABLE 的段地址。

(6)BX=1。

(7)DX=TABLE 的偏移地址。

  • 4.13
MOV DX,2012H
    MOV AX,5D68H
    MOV CX,1003H
    MOV BX,49A6H
    ADD AX,BX      (SUB AX,BX)
    ADC DX,CX        (SBB DX,CX)
  • 4.14
SUB AX,CX

SBB DX,0
  • 4.15
MOV AX,extra

MOV ES,AX
  • 4.16
;(1)     
MOV AL,16
ADD AL,X
MOV BL,5
IMUL BL
MOV Z,AX

;(2)
MOV BL,4
MOV AL,X
IDIV BL
SUB AL,Y
MOV Z,AX

;(3)
MOV AL,X
MOV BL,8
IMUL BL
MOV DX,AX
MOV AH,0
MOV AL,Y
MOV BL,16
IDIV BL
CBW
ADD DX,AX
MOV AH,0
MOV AL,W
IMUL AL
SUB DX,AX
MOV Z,DX

;(4)
MOV AL,X
ADD AL,Y
MOV BL,X
SUB BL,Y
MOV AH,0
IMUL BL
MOV Z,AX
MOV AL,X
IDIV Y
CBW
SUB Z,AX
  • 4.17

Z = (5+22-15)*14= 168

  • 4.18

从伪指令 END START 处获知程序从 START 标号开始。

  • 4.19

(1)减法:

MOV AX,8576H         
MOV BX,9988H         
SUB AX,BX 

结果:AX=EBEEH,CF=1,OF=0,ZF=0,SF=1

(2) 加法:

MOV AX,8576H         
MOV BX,9988H         
ADD AX,BX        

结果:AX=1EFEH,CF=1,OF=1,ZF=0,SF=0

  • 4.21
;(1)    
MOV AL,56H
MOV BL,34H
ADD AL,BL
DAA    
MOV Y1,AL
            
;(2)    
MOV AX,128H        
MOV BX,35H
SUB AX,BX
DAS
MOV Y2,AL

;(3)
MOV AL,68H        
MOV BL,23H
ADD AL,BL
MOV BL,45H
SUB AL,BL
DAS
MOV Y3,AL
  • 4.22
;(1)    
MOV AX,0708H
MOV BX,0406H
ADD AL,BL
ADD AH,BH        ;不用带进位加
AAA            ;加法调整,含进位调整
MOV BX,AX
XCHG AH,AL    ;高4位调整
AAA
MOV BH,AL
MOV Z1,BX        ;保存十位、各位,百位在CF中

;(2)    
MOV AX,0905H
MOV BX,0207H
SUB AL,BL
SUB AH,BH        ;不用带借位减
AAS            ;减法调整
MOV Z2,AX

;(3)    
MOV AX,0102H
MOV BX,0006H
MUL BX            ;乘法先不用调整
MOV BX,0303H
SUB AX,BX
AAS            ;减法调整
MOV Z3,AX


;(4)
MOV AX,0704H
MOV BX,0108H
ADD AL,BL
ADD AH,BH
AAA            ;加法调整
MOV BL,6
AAD            ;除法调整
DIV BL
MOV BH,AH        ;余数保存在BH
AND AX,000FH
AAA            ;商调整
MOV Z4,AX        ;保存商
  • 4.23

编程序。从键盘输入一个数字,去掉 ASCII 码后保存到 BUFF 单元。

.model small
.data
  buff db ?
.code
start:
mov ax,@data
mov ds,ax
mov ah,1            ;键盘输入
int 21h
sub al,30h            ;去掉ASCII码
mov buff,al
mov ah,4ch
int 21h
end start
  • 4.24

编程序。将键盘输入的小写字母变为大写字母显示在屏幕上。

.model small
.code
start:
mov ah,1            ;键盘输入
int 21h
sub al,20h            ;变为大写
mov dl,al
mov ah,2
int 21h
mov ah,4ch
int 21h
end start
  • 4.25

X 和 Y 都是字节型数据,编写将两数相加的结果显示出来的程序段。

.model small
.data
  x db 12h
  y db 34h
.code
start:
mov ax,@data
mov ds,ax
mov al,x
add al,y            ;结果为46H
mov ah,al        ;AH=46H
and al,0fh        ;AL=06H
mov cl,4
rol ah,cl            ;AH=64H
and ah,0fh        ;AH=04H
add ax,3030h        ;AX=3436H
mov bx,ax
mov dl,bh        ;显示4
mov ah,2        
int 21h
mov dl,bl        ;显示6
int 21h
mov ah,4ch
int 21h
end start
  • 4.26

编写程序,建立一个 0~9 的平方根表,查表可得某数的平方根。

data segment 
  x db '0.000','1.000','1.414','1.732','2.000'
    db '2.236','2.449','2.646','2.828','3.000'    ;建立字符表
  y db 5 dup(?)        ;存放查到平方根
  u db 3                ;要查的数
data ends
code segment
assume cs:code,ds:data
start:
mov ax,data
mov ds,ax
mov al,u                ;要查的数
mov cl,5
mul cl                ; (u×5=15号单元开始)
mov ah,0
mov bx,ax            ;地址保存到bx
mov si,0
let1:
mov al,x[bx]            ;取出平方根数字
mov y[si],al            ;存入y
inc si
inc bx
loop let1                ;循环取出5次
mov ah,4ch
int 21h
code ends
end start
  • 4.27

编写查表程序。建立一个班级姓名表,给出学号,可显示出其姓名。

.model small
.data
x1 db 'zhang yan  $'       ;姓名为10个字符宽度
x2 db 'li li       $'
x3 db 'wang lan   $'
x4 db 'zhao xue   $'
x5 db 'li jiang    $'
 u db 3                  ;要查的学号
.code 
start:
mov ax,@data
mov ds,ax
mov al,u                ;给出学号
mov cl,10
mul cl                ;u×10=30(号单元开始)
mov ah,0
mov dx,ax            ;地址保存到dx
mov ah,9                   ;9号功能显示字符串
int 21h
mov ah,4ch
int 21h
end start
  • 4.28

编程实现公式计算 Z=X/4+16Y。

.model small
.data
x  db 4        
y  db 6
z  db ?
.code 
start:
mov ax,@data
mov ds,ax
mov al,x        ;
mov cl,2
sar al,cl            ; X/4
mov cl,4
mov bl,y
sal bl,cl            ;16Y
add al,bl            ;X/4+16Y
mov z,al
mov ah,4ch
int 21h
end start
  • 4.29

编写程序段,将 AL 中的数乘以 6,与 CL 相减后再除以 3;把商保存到 Y 单元,余数保存到 Y + 1 单元。

.model small
.data
y  db ?,?
.code 
start:
mov ax,@data
mov ds,ax
mov al,3            ;设al=3
mov cl,6
mul  cl            ;al×6
mov cl,4            ;设cl=4
sub al,cl            ;相减
mov bl,3        
idiv bl               ; /3
mov y,al            ;商
mov y+1,ah        ;余数
mov ah,4ch
int 21h
end start

习题五答案

  • 5.11

进位标志 CF=1

  • 5.12

先把 AX 的值除以 8 等于 0246H,再把高 12 位屏蔽为 0,剩下 AL=06H 加上 30H 变为 ASCII 码显示出来。

  • 5.13

判断 X>0,是,Z=X-Y;否则 Z=X 的绝对值

  • 5.14

(1) 目的操作数是存储单元时,要用 PTR 伪操作指出单元的属性。

(2) DS 段寄存器使用非法

(3) 立即数使用非法。

(4) 目的操作数不允许是立即数

(5) 两个操作数不允许都是存储单元

(6) 移位次数超过 1 要用 CL 表示。

  • 5.15

AND AL,11011111B

  • 5.16

(1) AL=30H

(2) AL=B7H

(3) AL=C8H

(4) AL=38H

  • 5.27

分支程序设计。完成如下公式的计算,请写出程序。

 (X+3)/2    X>0
  Y=0         X=0
  X×4         X<0

程序:

DATA SEGMENT
    X  DB  23
    Y  DB  ?
DATA ENDS
CODE SEGMENT
    ASSUME  CS:CODE,DS:DATA
START:MOV AX,DATA
    MOV DS,AX
    MOV AL,X
    CMP  AL,0
    JE  SUB2
    JG  SUB1
    MOV CL,2
    SAL AL,CL
    JMP SHORT SUB2
SUB1:
    ADD  AL,3
    SAR  AL,1
SUB2:    
    MOV  Y,AL
    MOV AH,4CH
    INT 21H
CODE ENDS
END START
  • 5.28

设 X、Y、Z 为字节单元。如果 X≥0,Z=4X-Y/16,否则,Z=X 的绝对值。编程序实现。

程序如下:

DATA  SEGMENT
         X  DB  3
         Y  DB  5
         Z  DB  ?
    DATA ENDS
    CODE  SEGMENT
        ASSUME  CS:CODE,DS:DATA
    START: MOV AX,DATA
           MOV DS,AX
           MOV AL,X
           CMP AL,0
           JL SS1
           MOV CL,2
           SAL  AL,CL
           MOV  BL,Y
           MOV  CL,4
           SAR  BL,CL
           SUB  AL,BL
JMP  OUT1
     SS1:  NEG AL
OUT1:  MOV Z,AL
        MOV AH,4CH
        INT 21H
CODE  ENDS
        END START
  • 5.29

字数组 M 中有 10 个数据,分类统计其中正数、负数、0 的个数,分别存入 POSI、NEGA、ZERO 单元。

程序如下:

DATA1  SEGMENT
M     DW  21,-34,32,112,-324,0,76,0,48,50
POSI  DW  ?
NEGA  DW  ?
ZERO  DW  ?
DATA1  ENDS
CODE1  SEGMENT
        ASSUME  CS: CODE1,DS:DATA1
    START:    MOV  AX,DATA1
            MOV  DS,AX
            MOV  CX,10
            LEA  SI,M
    AGAIN:    CMP  WORD PTR [SI],0
            JL  LOWER
            JE  EQUAL
            INC  POSI
            JMP  LPP1
    LOWER:    INC  NEGA
            JMP LPP1  
    EQUAL:    INC  ZERO
    LPP1:    ADD  SI,2
            DEC CX
            JNZ AGAIN
            MOV AH,4CH
            INT 21H
CODE1  ENDS
        END  START
  • 5.30

试编写程序,从键盘接收一英文单词,以空格结束,将其存入 BUF 开始的存储单元中,并在最后加上字符串结束符 ’$’。

主要程序部分:

LEA        BX,BUF
LOP:    MOV    AH,1
        INT        21H
        CMP    AL,20H
        JE        NEXT
        MOV    [BX],AL
        INC        BX
        JMP        LOP
NEXT:    MOV    BYTE  PTR[BX],’$’
  • 5.31

编程。将 AX 寄存器中的 16 位数分成 4 组,每组 4 位,从低到高分别放在 AL,BL,CL,DL 中。

程序段:

START:MOV  AX,1234H
        MOV  BX,AX
        AND  AL,0FH            ;4
        AND  BL,0F0H            ;3
        AND  AH,0FH
        MOV  CL,AH            ;2
        AND  BH,0F0H
        MOV  DL,BH            ;1

习题六答案

  • 6.11

累加和 TOTAL=83

  • 6.12

循环统计 X 中 0 的个数

  • 6.13(1) 将 BB1:RCL AL,1 改为 BB1:ROL AL,1

(2) 将

BB2:CMP  [BX],’T’
    LOOPNE BB2

改为:

    DEC BX
BB2:INC BX
CMP  [BX],’T’
    LOOPNE BB2
  • 6.15

计算 Y=1×2+3×4+5×6+7×8+9×10 的程序段。

    MOV AL,1
    MOV BL,2
    MOV DX,0
    MOV CX,5
AA1:MUL BL
    ADD DX,AX
    INC BL
    MOV AL,BL
    INC BL
    LOOP AA1
  • 6.16

写程序段。查找 CATT 表中的字符”@”,找到后将 SIGN 单元置 1,否则 SIGN 单元置 0。

    catt db 'asd@ddd'
    sign db ?
    ……
mov ax,extra
mov es,ax
mov sign,0
mov al,'@'
lea di,catt
cld
mov cx,7
repnz scasb
jcxz nee
mov sign,1
nee: mov ah,4ch
    int 21h
  • 6.17

写程序段。在长度为 N 的字数组 VALUE 中统计负数的个数并保存到 AX 中。

value dw 2,-4,-5,3,6,6,-8
  n equ ($-value)/2                    ;元素个数
……
start: mov ax,data
    mov ds,ax
    mov cx,n
    mov bx,0
    mov ax,0
rept1:
       mov si,value[bx]            ;取出元素
       cmp si,0        
       jge let1                    ;≥0 转let1
       inc ax                    ;为负数,ax加1
let1: add bx,2
    loop rept1
  • 6.18

从键盘输入一个数字,在屏幕上显示出以该数字开始 10 个数字串。

CODE  SEGMENT
ASSUME  CS:CODE
START:    MOV  AH,1
INT  21H
MOV CX,10
MOV BL,AL
REPT1:    CMP BL,'9'
JLE NEXT
SUB  BL,10
NEXT:    MOV  DL,BL
MOV  AH,2
INT  21H
INC BL
LOOP  REPT1
MOV AH,4CH
INT 21H
CODE  ENDS
END  START
  • 6.19

编程。比较两个字符串是否相同,统计并显示出相同的字符个数和不同的字符个数。

data segment
bunch1  db  'stadent'
bunch2  db  'studEnt'
data ends
code segment
assume cs:code,ds:data,es:data
start:
mov ax,data
mov ds,ax
mov es,ax
lea si,bunch1
lea di,bunch2
mov bx,0        ;bh=相同的个数,bl=不同的个数
mov cx,7
let1:
mov al,[si]
cmp al,[di]        ;两字符比较
jz equl            ;相同转equl
inc bl            ;不同bl加1
jmp out1
equl: inc bh
out1:inc si
inc di
loop let1
mov dl,'n'        ;显示'n',代表不同
mov ah,2h
int 21h
add bl,30h        ;加上ASCII码
mov dl,bl        ;显示不同的个数
int 21h
mov dl,'e'        ;显示'e',代表相同
int 21h
add bh,30h
mov dl,bh        ;显示相同的个数
int 21h            
mov ah,4ch
int 21h
code ends
end start
  • 6.21

STRI 单元存有 10 个字符的字符串,以 0 结尾,编程去掉其中的空格符,并将后续字符向前递补。

        DATA  SEGMENT
            STR  DB  ‘SDABF G H0’
        DATA ENDS
        CODE  SEGMENT
            ASSUME  CS:CODE,DS:DATA
START:MOV AX,DATA
        MOV  DS,AX
        LEA  DI,STR
        SPACE:MOV  CX,10
                MOV AL,[DI]
                CMP  AL,0
                JE  OUT
                CMP  AL,20H
                JE  DELETE
                JMP  EXIT
                SUB  CX,DI
                MOV  SI,DI
        DELETE:
                MOV  BL,[SI+1]
                MOV  [SI],BL
                INC  SI
                LOOP  DELETE
        EXIT:JMP  SPACE
        OUT:MOV AH,4CH
                INT 21H
        CODE  ENDS
                END  START
  • 6.23

将内存中用 ASCII 码表示的 100 以内的十进制数转变为二进制数。十进制数不够 3 位以 20H(空格)补齐。

设计思路:

(1)用 EQU 伪指令获得需转换的十进制数的个数;

(2)用双重循环。外循环控制个数,用 x 作为中间变量;

(3)内循环将一个 3 位十进制数去掉 ASCII 码后按位数扩大 10 倍再相加,保存后即存储为二进制数;

(4)分两个数组保存 ASCII 码表示的十进制数和转换后的二进制数。

程序如下:

; 6-23.asm 将内存中用ASCII码表示的100以内的十进制数转变为二进制数
data segment
  score1 db 36h,37h,20h,31h,30h,30h,38h,35h,20h,31h,30h,30h        ;即67,100,85,100
  x   dw ?
  n   equ 3                            ;三位数
  num equ (x-score1)/n                ;十进制数个数
  score2 dw num dup(0)                 ;保存转换后的二进制数
data ends
code segment
   assume cs:code,ds:data
start:     mov ax,data
        mov ds,ax
        mov cx,num 
        mov si,-2
        mov bx,0
rept1:    push cx                        ;保存外循环次数
        mov cx,n
rept2:    mov al,score1[bx]            ;从score1取数
        cmp al,30h                    ;判断是否0-9
        jl exit
        cmp al,39h
        jg exit
        and ax,000fh                ;去掉ASCII码
        xchg ax,x    
        mov dx,10                    ;将ax中前一次形成的数扩大10倍
        mul dx    
        xchg ax,x
        add x,ax                    ;相加后保存到x
exit:    inc bx                        ;取下一位数
        loop rept2
        pop cx                        ;弹出外循环次数
        add si,2
        mov ax,x
        mov score2[si],ax            ;转换后的数据保存到score2
        mov x,0    
        loop rept1
        mov ah,4ch
        int 21h
code ends
end start

运行结果:

可以看到,67 转换为 0043,100 转换为 0064,85 转换为 0055。在 DEBUG 下显示的内存单元是十六进制表示,实际存储的是二进制数。

习题七答案

  • 7.12

功能:两个字节数相加。X 和 BL 相加保存到 Y。

  • 7.13

功能:键盘输入的字符保存到 KEY 单元中,直到按回车为止。

  • 7.14

功能:将 X 单元中的十六进制 3AH 变为十进制入栈保存,AH 中为余数。先将 0008H 入栈,再将 0005H 入栈,结果为 58。

  • 7.16

写出子程序,从键盘输入一个多位十进制数,并分别保存到 BUFFER 开始的单元中。

        KEY_IN  PROC 
            PUSH AX
            PUSH BX
            MOV BX,0
LET1:MOV AH,1
            INT 21H
            CMP AL,0DH                ;输入回车退出
            JZ EXIT
            MOV BUFFER[BX],AL        ;保存到BUFFER
            INC BX
            JMP LET1
        EXIT:POP BX
            POP AX
            RET
        KEY_IN ENDP
  • 7.17

从键盘输入多位数字,转换成十进制数并保存到 X 单元中。

        KEY_IN_DEC  PROC 
            PUSH AX
            PUSH BX
            MOV X,0
            MOV BX,0
            MOV SI,0
LET1:MOV AH,1
            INT 21H
            CMP AL,0DH                ;输入回车退出
            JZ EXIT
            MOV BUFFER[SI],AL        ;保存到BUFFER
            INC SI
            JMP LET1
        EXIT:MOV CX,SI                ;位数放在CX
            MOV SI,0
        LET2:MOV AL, BUFFER[SI]
            SUB AL,30H
            MOV AH, 0
            XCHG AX,X                ;形成十进制数
            MOV BX,10
            MUL BX
            XCHG AX,X
            ADD X,AX                ;保存
            INC SI
            LOOP LET2
            POP BX
            POP AX
            RET
        KEY_IN _DEC ENDP
  • 7.23

写出对内存单元 X 中的补码求真值子程序,补码保存在 AX 中。

calcu  proc
    push ax
    push bx
    push si
mov ax,0
mov al,x
and al,al
jns zz
neg al
mov fuhao,'-'
zz:
mov si,0
mov bx,10        ;将ax变为十进制数真值
let1:
mov dx,0
inc si            ;统计余数个数
idiv bx
mov y[si], dx        ;在y单元保存余数
cmp ax,0
jnz let1
        pop si
        pop bx
        pop ax
        ret
    calcu endp
  • 7.30

编制一个计算数组中所有负数之和的子程序。并利用此子程序分别计算 A 数组和 B 数组中的负数之和,结果分别放在 SUM1 和 SUM2 单元中。

DATA  SEGMENT
    A  DB  9,-8,-7,6,5
    B  DB  -8,7,6,-5,4
    SUM1  DB  ?
SUM2  DB  ?
DATA  ENDS
CODE  SEGMENT
    ASSUME  CS:CODE,DS:DATA
START:MOV  AX,DATA
        MOV  DS,AX
        MOV  CX,5
        MOV  SI,OFFSET  A
        CALL  LADD
        MOV  SUM1,BL
        MOV  SI,OFFSET  B
        CALL  LADD
        MOV   SUM2,BL
        MOV AH,4CH
        INT 21H
LADD  PROC  NEAR
        PUSH  CX
        PUSH  AX
        PUSH  SI
        XOR  BL,BL
NEXT:    MOV  AL, [SI]
        AND  AL,AL
        JNS  JJJ
        ADD  BL,AL
JJJ:    INC  SI
        LOOP  NEXT
        POP  SI
        POP  AX
        POP  CX
        RET
LADD  ENDP
CODE ENDS
        END  START

习题八答案

  • 8.16

宏的作用:DOS 功能调用。功能号用哑元指出。

  • 8.17

宏的作用:两个操作数相加,结果保存在第 3 个数中。

  • 8.18

宏的作用:DOS 的 2 号显示功能。

  • 8.19

宏的作用:定义 VALUE 数组,数组长度和初值由哑元指出。

  • 8.20

缺少标号定义 LOCAL LETT1。宏的作用:两个哑元相减,结果为负则求补。

  • 8.27

程序:

.model small
.stack 100h
.code
start:
input                        ;键盘输入
add al,20h                ; 大写变为小写
output al                    ; 显示
mov ah,4ch
int 21h
end start
  • 8.28

程序:

.model small
.data  
alpha db ‘Computer’
.code
start:
display alpha                ;显示字串
mov ah,4ch
int 21h
end start
  • 8.29

程序:

.model small
.stack 100h
.code
start:
input                        ;键盘输入
cmp al,‘-’
jnz start
neg x                        ;求补
mov ah,4ch
int 21h
end start
  • 8.30

程序:

.model small
.stack 100h
.code
start:
input                        ;键盘输入
mov bl,al
input                        ;输入第2个数
add al,bl
mov ah,0
aaa                        ;非压缩BCD码加法调整
add ax,3030h    
output ah                    ;显示高位
output al                    ;显示低位
mov ah,4ch
int 21h
end start

习题九答案

  • 9.26

在屏幕的 row1、rank1 到 row2、rank2 开窗口,清窗口,设置字符颜色为 color。

  • 9.27

将光标设置在 5 行 10 列上。

  • 9.28

回车换行宏。

  • 9.29

读取时钟计数器当前计数值,cx 保存高位,dx 保存低位;判断计数是否到 91 次(5 秒),没到,继续循环读取,到 5 秒后做下面内容。

  • 9.30

设置 1CH 号中断的中断向量(win_time),将其保存到中断向量表中。

  • 9.35

编程实现在窗口中将键盘输入的小写字母加密后显示出来。

程序如下:

include 9-3.mac        ;参见教材9.3.1节示例9-3,9-3.mac宏库
.model small
.data
letter db 'Input Letter: $'
cont db ?
.code
start:
mov ax,@data            
mov ds,ax
clearsc                ;清屏
clearsw                ;窗口清屏
reptt:
;置显示光标
mov ah,2
mov dh,11                ;在11行30列显示
mov dl,30
mov bh,0
int 10h
;显示串
mov ah,9
mov dx,offset letter
int 21h
;置输入光标
mov ah,2
mov dh,15                ;在15行30列输入
mov dl,30
mov bh,0
int 10h
;输入小写字母
mov ah,1
int 21h
add al,20h                ;加密
;显示加密后的字符
mov dl,al
mov ah,2
int 21h
;开窗口
mov ah,6
mov al,1                ;上卷1行
mov ch,8                ;从8行30列到15行60列
mov cl,30
mov dh,15
mov dl,60
mov bh,27h            ;绿底灰字
int 10h
inc cont                ;可输入3次
cmp cont,3
jne reptt
out1:
mov ah,4ch
int 21h
end start
  • 9.36

编写程序,在屏幕上显示彩色的 26 个英文字母。

程序如下:

.model small
.data
letter db ?
n='a'                    ;重复汇编
m=1eh                ;蓝底黄字开始
rept  26                ;26个小写字母
 db n,m
n=n+1
m=m+1
endm
.code
start:
mov ax,@data            ;各个段都在代码段中
mov ds,ax
;开窗口
mov ah,06h
mov al,0
mov bh,37h            ;白底黑字0f0h,兰灰底灰白字37h,黄底白字0e7h
mov ch,3                ;从8行30列到15行60列
mov cl,3
mov dh,15
mov dl,60
int 10h
;置光标
locate:
mov ah,2
mov dh,6                ;光标在6行30列
mov dl,30
mov bh,0
int 10h
;显示彩色的26个英文字母
mov bx,offset letter+1
mov bp,bx
mov bx,seg letter+1
mov es,bx
mov ah,13h
mov al,3
mov bh,0
mov cx,26                ;26个字母
int 10h
mov ah,4ch
int 21h
end start
  • 9.37

编写程序,在窗口中将键盘输入的一串字符中的大写字母和小写字母的个数分别统计并显示出来。

程序如下:

include 9-4.mac        ;参见教材9.5.1节示例9-4,9-4.mac宏库
.model small
.data
mess1 db 'input:  $'
mess2  db 29,32 dup(?)    
daxie db ?
xiaoxie db ?    
.code
start:
mov ax,@data            
mov ds,ax
clearsc                        ;清屏
clearsw  8,30,15,60,27h            ;开窗口,绿底灰白字
cursor 12,30                    ;置显示光标
;显示提示
mov ah,9
mov dx,offset mess1
int 21h
;输入串
mov al,0
mov ah,10
mov dx,offset mess2
int 21h
;统计
mov cx,0
mov cl,mess2+1                ;输入的个数
mov bx,2                        ;从第2个单元存放键入的字母
let1:
mov al,mess2[bx]
test al,20h                        ;区分大小写
jz let2                            ;为0,即大写转
inc xiaoxie                     ;小写加1
jmp let3
let2:
inc daxie                        ;大写加1
let3:
inc bx
loop let1
windows  8,30,15,60,27h        ;窗口内上卷
cursor 14,30                    ;在16行30列显示
add xiaoxie,30h
displ xiaoxie                    ;显示小写个数
windows  8,30,15,60,27h        ;窗口内上卷
add daxie,30h            
displ daxie                        ;显示大写个数
out1:
mov ah,4ch
int 21h
end start
  • 9.38

编写对键盘输入一段英文的操作计时的程序。

程序如下:

include 9-4.mac
.model small
.data
letter1 db 'Time start=  ','$' 
letter2 db 'Time end  =  ','$'
letter3 db 'Time total=  ','$'
input db 100,102 dup(?)
hour db ?
minutes db ?
seconds db ?
persec db ?
cont db 0
.code
start:
mov ax,@data            
mov ds,ax
clearsc                    ;清屏
cursor  2,50                ;置光标
mov ah,9
mov dx,offset letter1            ;显示串1
int 21h
sss:
;读时间并显示
mov ah,2ch                ;CH=小时,CL=分,DH=秒,DL=百分秒
int 21h
mov bx,0
mov bl,ch
call disp_2_10                ;显示小时
displ ':'                    ;显示:
mov bx,0
mov bl,cl
call disp_2_10                ;分
displ ':'                    ;显示:
mov bx,0
mov bl,dh
call disp_2_10                ;秒
displ ':'                    ;显示:
mov bx,0
mov bl,dl
call disp_2_10                ;百分秒
sub ch,hour                ;计算时间差
sub cl,minutes
sub dh,seconds
sub dl,persec
mov hour,ch                ;保存时间差
mov minutes,cl
mov seconds,dh
mov persec,dl
inc cont
cmp cont,2                    ;显示2次时间
jz out1
cursor  7,10                ;置输入光标
mov dx,offset input            ;键盘输入
mov ah,10
int 21h
cursor  3,50                ;置光标
;显示串2
mov ah,9
mov dx,offset letter2
int 21h
jmp sss
out1:
cursor  4,50                ;置光标
mov ah,9
mov dx,offset letter3            ;显示串3
int 21h
;显示时间差
mov cx,3
mov si,offset hour
mov bx,0
www:
mov bl,[si]                    ;取出时、分、秒
call disp_2_10                ;3次调用
displ ':'                    ;显示:
inc si
loop www
mov ah,4ch
int 21h

;子程序。二-十进制数转换。bx值用十进制显示。
disp_2_10 proc 
store_ss                    ;保护现场
mov ax,bx                    ;bx传参
mov cx,0
mov bx,10                    ;将ax变为十进制数
let1:
mov dx,0
inc cx                        ;统计余数个数
idiv bx
push dx                    ;保存余数
cmp ax,0
jnz let1
let2:                        ;显示结果
pop ax                    ;将余数弹入ax
add ax,0030h                ;调整为ascii码
mov dl,al
mov ah,2
int 21h
loop let2
restore_ss                    ;恢复现场
ret
disp_2_10 endp
end start

类似文章