JB INPUT ;不是‘A~F’的数重新输入CMP AL, 46H ;>F吗
JA INPUT ;不是‘A~F’的数重新输入
AND AL, 0FH ;转换为:1010B~1111B
ADD AL, 9
BINARY: OR BL, AL ;将键盘输入的数进行组合
DEL CH
JNZ INPUT
DISPN: MOV CX, 16 ;将16位二进制数一位位地转换成ASCII码显示
DISP: MOV DL, 0
ROL BX, 1
RCL DL, 1
OR DL, 30H
MOV AH, 2 ;进行显示
INT 21H
LOOP DISP
STOP: RET
8、 设有一段英文,其字符变量名为ENG,并以$字符结束。试编写一程序,查对单词SUN在该文中的出现次数,并以格式“SUN:xxxx”显示出次数。
答:程序如下:
DSEG SEGMENT
ENG DB ‘Here is sun, sun ,…,$’
DISP DB ‘SUN:’
DAT DB ‘0000’ , 0DH, 0AH, ‘$’
KEYWORD DB ‘sun’
DSEG ENDS
;--------------------------------------------------------------------------
CSEG SEGMENT
MAIN PROC FAR
ASSUME CS: CSEG, DS: DSEG, ES: DSEG
START: PUSH DS ;设置返回DOS
SUB AX, AX
PUSH AX
MOV AX, DSEG
MOV DS, AX ;给DS赋值
MOV ES, AX ;给ES赋值
BEGIN: MOV AX, 0
MOV DX, DISP-ENG-2 ;计算ENG的长度(每次比较sun,因此比较次数-2)
LEA BX, ENG
COMP: MOV DI, BX
LEA SI, KEYWORD
MOV CX, 3
REPE CMPSB ;串比较
JNZ NOMATCH
INC AX ;是,SUN的个数加1
ADD BX, 2
NOMATCH: INC BX ;指向ENG的下一个字母
DEC DX
JNZ COMP
DONE: MOV CH, 4 ;将次数转换为16进制数的ASCII码
MOV CL, 4
LEA BX, DAT ;转换结果存入DAT单元中
DONE1: ROL AX, CL
MOV DX, AX
AND DL, 0FH ;取一位16进制数
ADD DL, 30H
CMP DL, 39H
JLE STORE
ADD DL, 07H ;是“A~F”所以要加7
STORE: MOV [BX], DL ;转换结果存入DAT单元中
INC BX
DEC CH
JNZ DONE1
DISPLAY: LEA DX, DISP ;显示字符串程序(将DISP和DAT一起显示)
MOV AH, 09H
INT 21H
RET
MAIN ENDP
CSEG ENDS ;以上定义代码段
;--------------------------------------------------------------------------
END START
9、 从键盘输入一系列以$为结束符的字符串,然后对其中的非数字字符计数,并显示出计数结果。
答:程序段如下:
DSEG SEGMENT
BUFF DB 50 DUP (‘ ’)
COUNT DW 0
DSEG ENDS
┇
BEGIN: LEA BX, BUFF
MOV COUNT, 0
INPUT: MOV AH, 01 ;从键盘输入一个字符的功能调用
INT 21H
MOV [BX], AL
INC BX
CMP AL, ‘$’ ;是$结束符吗
JNZ INPUT ;不是,继续输入
LEA BX, BUFF ;对非数字字符进行计数
NEXT: MOV CL, [BX]
INC BX
CMP CL, ‘$’ JZ DISP
CMP CL, 30H JB NEXT
CMP CL, 39H JA NEXT
INC COUNT JMP NEXT
DISP: ┇ ;是$结束符,则转去显示
;小于0是非数字字符
;大于9是非数字字符
;个数+1
;16进制数显示程序段(省略)
10、 有一个首地址为MEM的100D字数组,试编制程序删除数组中所有为0的项,并将后续项向前压缩,最后将数组的剩余部分补上0。
答:程序如下:
DSEG SEGMENT
MEM DW 100 DUP ()
DSEG ENDS
;--------------------------------------------------------------------------
CSEG SEGMENT
MAIN PROC FAR
ASSUME CS: CSEG, DS: DSEG
START: PUSH DS ;设置返回DOS
SUB AX, AX
PUSH AX
MOV AX, DSEG
MOV DS, AX ;给DS赋值
BEGIN: MOV SI, (100-1)*2 ;(SI)指向MEM的末元素的首地址
MOV BX, -2 ;地址指针的初值
MOV CX, 100
COMP: ADD BX, 2
CMP MEM [BX], 0
JZ CONS
LOOP COMP
JMP FINISH ;比较完了,已无0则结束
CONS: MOV DI, BX
CONS1: CMP DI, SI ;到了最后单元码
JAE NOMOV
MOV AX, MEM [DI+2] ;后面的元素向前移位
MOV MEM [DI], AX
ADD DI, 2
JMP CONS1
NOMOV: MOV WORD PTR [SI], 0 ;最后单元补0
LOOP COMP
FINISH: RET
MAIN ENDP
CSEG ENDS ;以上定义代码段
;--------------------------------------------------------------------------
END START
11、 在STRING到STRING+99单元中存放着一个字符串,试编制一个程序测试该字符串中是否存在数字,如有则把CL的第5位置1,否则将该位置0。
答:程序如下:
DSEG SEGMENT
STRING DB 100 DUP ()
DSEG ENDS
;--------------------------------------------------------------------------
CSEG SEGMENT
MAIN PROC FAR
ASSUME CS: CSEG, DS: DSEG
START: PUSH DS ;设置返回DOS
SUB AX, AX
PUSH AX
MOV AX, DSEG
MOV DS, AX ;给DS赋值
BEGIN: MOV SI, 0 ;(SI)作为地址指针的变化值
MOV CX, 100
REPEAT: MOV AL, STRING [SI]
CMP AL, 30H
JB GO_ON
CMP AL, 39H
JA GO_ON
OR CL, 20H ;存在数字把CL的第5位置1
JMP EXIT
GO_ON: INC SI
LOOP REPEAT
AND CL, 0DFH ;不存在数字把CL的第5位置0
EXIT: RET
MAIN ENDP
CSEG ENDS ;以上定义代码段
;--------------------------------------------------------------------------
END START
12、 在首地址为TABLE的数组中按递增次序存放着100H个16位补码数,试编写一个程序把出现次数最多的数及其出现次数分别存放于AX和CX中。
答:程序如下:
DSEG SEGMENT
TABLE DW 100H DUP () ;数组中的数据是按增序排列的
DATA DW
COUNT DW 0
DSEG ENDS
;--------------------------------------------------------------------------
CSEG SEGMENT
MAIN PROC FAR
ASSUME CS: CSEG, DS: DSEG
START: PUSH DS ;设置返回DOS
SUB AX, AX
PUSH AX
MOV AX, DSEG
MOV DS, AX ;给DS赋值
BEGIN: MOV CX, 100H ;循环计数器
MOV SI, 0
NEXT: MOV DX, 0
MOV AX, TABLE [SI]
COMP: CMP TABLE [SI], AX ;计算一个数的出现次数
JNE ADDR
INC DX
ADD SI, 2
LOOP COMP
ADDR: CMP DX, COUNT ;此数出现的次数最多吗
JLE DONE
MOV COUNT, DX ;目前此数出现的次数最多,记下次数
MOV DATA, AX ;记下此数
DONE: LOOP NEXT ;准备取下一个数
MOV CX, COUNT ;出现最多的次数存入(CX)
MOV AX, DATA ;出现最多的数存入(AX)
RET
MAIN ENDP
CSEG ENDS ;以上定义代码段
;--------------------------------------------------------------------------
END START
13、 数据段中已定义了一个有n个字数据的数组M,试编写一程序求出M中绝对值最大的数,把它放在数据段的M+2n单元中,并将该数的偏移地址存放在M+2(n+1)单元中。
答:程序如下:
DSEG SEGMENT
n EQU 100H ;假设n=100H
M DW n DUP ()
DATA DW ;M+2n单元
ADDR DW ;M+2(n+1)单元
DSEG ENDS
;--------------------------------------------------------------------------
CSEG SEGMENT
MAIN PROC FAR
ASSUME CS: CSEG, DS: DSEG
START: PUSH DS ;设置返回DOS
SUB AX, AX
PUSH AX
MOV AX, DSEG
MOV DS, AX ;给DS赋值
BEGIN: MOV CX, n ;循环计数器
LEA DI, M
MOV AX, [DI] ;取第一个数
MOV ADDR, DI ;记下绝对值最大的数的地址
CMP AX, 0 ;此数是正数吗
JNS ZHEN ;是正数,即为绝对值,转去判断下一个数
NEG AX ;不是正数,变为其绝对值
ZHEN: MOV BX, [DI]
CMP BX, 0 ;此数是正数吗
JNS COMP ;是正数,即为绝对值,转去比较绝对值大小
NEG BX ;不是正数,变为其绝对值
COMP: CMP AX, BX ;判断绝对值大小
JAE ADDRESS
MOV AX, BX ;(AX)<(BX),使(AX)中为绝对值最大的数
MOV ADDR, DI ;记下绝对值最大的数的地址
ADDRESS: ADD DI, 2
LOOP ZHEN
MOV DATA, AX ;记下此数
RET
MAIN ENDP
CSEG ENDS ;以上定义代码段
;--------------------------------------------------------------------------
END START
14、 在首地址为DATA的字数组中存放着100H个16位补码数,试编写一个程序求出它们的平均值放在AX寄存器中;并求出数组中有多少个数小于此平均值,将结果放在BX寄存器中。
答:程序如下:
DSEG SEGMENT
DATA DW 100H DUP ()
DSEG ENDS
;--------------------------------------------------------------------------
CSEG SEGMENT
MAIN PROC FAR
ASSUME CS: CSEG, DS: DSEG
START: PUSH DS ;设置返回DOS
SUB AX, AX
PUSH AX
MOV AX, DSEG
MOV DS, AX ;给DS赋值
BEGIN: MOV CX, 100H ;循环计数器
MOV SI, 0
MOV BX, 0 ;和((DI),(BX))的初始值
MOV DI, 0
NEXT: MOV AX, DATA [SI]
CWD
ADD BX, AX ;求和
ADC DI, DX ;加上进位位
ADD SI, 2
LOOP NEXT
MOV DX, DI ;将((DI),(BX))中的累加和放入((DX),(AX))中
MOV AX, BX
MOV CX, 100H
IDIV CX ;带符号数求平均值,放入(AX)中
MOV BX, 0
MOV SI, 0
COMP: CMP AX, DATA [SI] ;寻找小于平均值的数
JLE NO
INC BX ;小于平均值数的个数+1
NO: ADD SI, 2
LOOP COMP
RET
MAIN ENDP
CSEG ENDS ;以上定义代码段
;--------------------------------------------------------------------------
END START
15、 试编制一个程序把AX中的16进制数转换为ASCII码,并将对应的ASCII码依次存放到MEM数组中的四个字节中。例如,当(AX)=2A49H时,程序执行完后,MEM中的4个字节内容为39H,34H,41H,32H。
答:程序如下:
DSEG SEGMENT
MEM DB 4 DUP ()
N DW 2A49H
DSEG ENDS
;--------------------------------------------------------------------------
CSEG SEGMENT
MAIN PROC FAR
ASSUME CS: CSEG, DS: DSEG
START: PUSH DS ;设置返回DOS
SUB AX, AX
PUSH AX
MOV AX, DSEG
MOV DS, AX ;给DS赋值
BEGIN: MOV CH, 4 ;循环计数器
MOV CL, 4
MOV AX, N
LEA BX, MEM
ROTATE: MOV DL, AL ;从最低四位开始转换为ASCII码
AND DL, 0FH
ADD DL, 30H
CMP DL, 3AH ;是0~9吗
JL NEXT
ADD DL, 07H ;是A~F
NEXT: MOV [BX], DL ;转换的ASCII码送入MEM中
INC BX
ROR AX, CL ;准备转换下一位
DEC CH
JNZ ROTATE
RET
MAIN ENDP
CSEG ENDS ;以上定义代码段
;--------------------------------------------------------------------------
END START
16、 把0~100D之间的30个数存入以GRADE为首地址的30字数组中,GRADE+i表示学号为i+1的学生的成绩。另一个数组RANK为30个学生的名次表,其中RANK+i的内容是学号为i+1的学生的名次。编写一程序,根据GRADE中的学生成绩,将学生名次填入RANK数组中。(提示:一个学生的名次等于成绩高于这个学生的人数加1。)
答:程序如下:
DSEG SEGMENT
GRADE DW 30 DUP () ;假设已预先存好30名学生的成绩
RANK DW 30 DUP ()
DSEG ENDS
;--------------------------------------------------------------------------
CSEG SEGMENT
MAIN PROC FAR
ASSUME CS: CSEG, DS: DSEG
START: PUSH DS ;设置返回DOS
SUB AX, AX
PUSH AX
MOV AX, DSEG
MOV DS, AX ;给DS赋值
BEGIN: MOV DI, 0
MOV CX, 30 ;外循环计数器
LOOP1: PUSH CX
MOV CX, 30 ;内循环计数器
MOV SI, 0
MOV AX, GRADE [DI]
MOV DX, 1 ;起始名次为第1名
LOOP2: CMP GRADE [SI], AX ;成绩比较
JBE GO_ON
INC DX ;名次+1
GO_ON: ADD SI, 2
LOOP LOOP2
POP CX
MOV RNAK [DI], DX ;名次存入RANK数组
ADD DI, 2
LOOP LOOP1
RET
MAIN ENDP
CSEG ENDS ;以上定义代码段
;--------------------------------------------------------------------------
END START
17、 已知数组A包含15个互不相等的整数,数组B包含20个互不相等的整数。试编制一程序把既在A中又在B中出现的整数存放于数组C中。
答:程序如下:
DSEG SEGMENT
A DW 15 DUP ()
B DW 20 DUP ()
C DW 15 DUP (‘ ’)
DSEG ENDS
;--------------------------------------------------------------------------
CSEG SEGMENT
MAIN PROC FAR
ASSUME CS: CSEG, DS: DSEG
START: PUSH DS ;设置返回DOS
SUB AX, AX
PUSH AX
MOV AX, DSEG
MOV DS, AX ;给DS赋值
BEGIN: MOV SI, 0
MOV BX, 0
MOV CX, 15 ;外循环计数器
LOOP1: PUSH CX
MOV CX, 20 ;内循环计数器
MOV DI, 0
MOV AX, A [SI] ;取A数组中的一个数
LOOP2: CMP B [DI], AX ;和B数组中的数相等吗
JNE NO
MOV C [BX], AX ;相等存入C数组中
ADD BX, 2
NO: ADD DI, 2
LOOP LOOP2
ADD SI, 2
POP CX
LOOP LOOP1
RET
MAIN ENDP
CSEG ENDS ;以上定义代码段
;--------------------------------------------------------------------------
END START
18、 设在A、B和C单元中分别存放着三个数。若三个数都不是0,则求出三数之和存放在D单元中;若其中有一个数为0,则把其它两单元也清0。请编写此程序。
答:程序如下:
DSEG SEGMENT
A DW
B DW
C DW
D DW 0
DSEG ENDS
;--------------------------------------------------------------------------
CSEG SEGMENT
MAIN PROC FAR
ASSUME CS: CSEG, DS: DSEG
START: PUSH DS ;设置返回DOS
SUB AX, AX
PUSH AX
MOV AX, DSEG
MOV DS, AX ;给DS赋值
BEGIN: CMP A, 0
JE NEXT
CMP B, 0
JE NEXT
CMP C, 0
JE NEXT
MOV AX, A
ADD AX, B
ADD AX, C
MOV D, AX
JMP SHORT EXIT
NEXT: MOV A, 0
MOV B, 0
MOV C, 0
EXIT: RET
MAIN ENDP
CSEG ENDS ;以上定义代码段
;--------------------------------------------------------------------------
END START
19、 试编写一程序,要求比较数组ARRAY中的三个16位补码数,并根据比较结果在终端上显示如下信息:
(1) 如果三个数都不相等则显示0;
(2) 如果三个数有二个数相等则显示1;
(3) 如果三个数都相等则显示2。
答:程序如下:
DSEG SEGMENT
ARRAY DW 3 DUP ()
DSEG ENDS
;--------------------------------------------------------------------------
CSEG SEGMENT
MAIN PROC FAR
ASSUME CS: CSEG, DS: DSEG
START: PUSH DS ;设置返回DOS
SUB AX, AX
PUSH AX
MOV AX, DSEG
MOV DS, AX ;给DS赋值
BEGIN: LEA SI, ARRAY
MOV DX, 0 ;(DX)用于存放所求的结果
MOV AX, [SI]
MOV BX, [SI+2]
CMP AX, BX ;比较第一和第二两个数是否相等
JNE NEXT1
INC DX
NEXT1: CMP JNE NEXT2
INC DX
NEXT2: CMP JNE NUM
INC DX
NUM: CMP JL DISP
[SI+4], AX [SI+4], BX DX, 3
;比较第一和第三两个数是否相等 ;比较第二和第三两个数是否相等
DEC DX
DISP: ADD DL, 30H ;转换为ASCII码
MOV AH, 2 ;显示一个字符
INT 21H
RET
MAIN ENDP
CSEG ENDS ;以上定义代码段
;--------------------------------------------------------------------------
END START
20、 从键盘输入一系列字符(以回车符结束),并按字母、数字、及其它字符分类计数,最后显示出这三类的计数结果。
答:程序如下:
DSEG SEGMENT
ALPHABET DB ‘输入的字母字符个数为:’, ‘$’
NUMBER DB ‘输入的数字字符个数为:’, ‘$’
OTHER DB ‘输入的其它字符个数为:’, ‘$’
CRLF DB 0DH, 0AH, ‘$’
DSEG ENDS
;--------------------------------------------------------------------------
CSEG SEGMENT
MAIN PROC FAR
ASSUME CS: CSEG, DS: DSEG
START: PUSH DS ;设置返回DOS
SUB AX, AX
PUSH AX
MOV AX, DSEG
MOV DS, AX ;给DS赋值
BEGIN: MOV BX, 0 ;字母字符计数器
MOV SI, 0 ;数字字符计数器
MOV DI, 0 ;其它字符计数器
INPUT: MOV AH, 1 ;输入一个字符
INT 21H
CMP AL, 0DH ;是回车符吗
JE DISP
CMP AL, 30H ;<数字0吗
JAE NEXT1
OTHER: INC DI ;是其它字符
JMP SHORT INPUT
NEXT1: CMP AL, 39H ;>数字9吗
JA NEXT2
INC SI ;是数字字符
JMP SHORT INPUT
NEXT2: CMP AL, 41H ;<字母A吗
JAE NEXT3
JMP SHORT OTHER ;是其它字符
NEXT3: CMP AL, 5AH ;>字母Z吗
JA NEXT4
INC BX ;是字母字符A~Z
JMP SHORT INPUT
NEXT4: CMP AL, 61H ;<字母a吗
JAE NEXT5
JMP SHORT OTHER ;是其它字符
NEXT5: CMP AL, 7AH ;>字母z吗
JA SHORT OTHER ;是其它字符
INC BX ;是字母字符a~z
JMP SHORT INPUT
DISP: LEA DX, ALPHABET
CALL DISPLAY
LEA DX, NUMBER
MOV BX, SI
CALL DISPLAY
LEA DX, OTHER
MOV BX, DI
CALL DISPLAY
RET
MAIN ENDP
;--------------------------------------------------------------------------
DISPLAY PROC NEAR
MOV AH, 09H ;显示字符串功能调用
INT 21H
CALL BINIHEX ;调把BX中二进制数转换为16进制显示子程序
LEA DX, CRLF
MOV AH, 09H ;显示回车换行
INT 21H
RET
DISPLAY ENDP
;--------------------------------------------------------------------------
BINIHEX PROC NEAR ;将BX中二进制数转换为16进制数显示子程序
MOV CH, 4
ROTATE: MOV CL, 4
ROL BX, CL
MOV DL, BL
AND DL, 0FH
ADD DL, 30H
CMP DL, 3AH ;是A~F吗
JL PRINT_IT
ADD DL, 07H
PRINT_IT: MOV AH, 02H INT 21H
DEC CH
JNZ ROTATE
RET
;显示一个字符
BINIHEX ENDP
CSEG ENDS ;以上定义代码段
;--------------------------------------------------------------------------
END START
21、 已定义了两个整数变量A和B,试编写程序完成下列功能:
(1) 若两个数中有一个是奇数,则将奇数存入A中,偶数存入B中;
(2) 若两个数中均为奇数,则将两数加1后存回原变量;
(3) 若两个数中均为偶数,则两个变量均不改变。
答:程序如下:
DSEG SEGMENT
A DW
B DW
DSEG ENDS
;--------------------------------------------------------------------------
CSEG SEGMENT
MAIN PROC FAR
ASSUME CS: CSEG, DS: DSEG
START: PUSH DS ;设置返回DOS
SUB AX, AX
PUSH AX
MOV AX, DSEG
MOV DS, AX ;给DS赋值
BEGIN: MOV AX, A
MOV BX, B
XOR AX, BX
TEST AX, 0001H ;A和B同为奇数或偶数吗
JZ CLASS ;A和B都为奇数或偶数,转走
TEST BX, 0001H
JZ EXIT ;B为偶数,转走
XCHG BX, A ;A为偶数,将奇数存入A中
MOV B, BX ;将偶数存入B中
JMP EXIT
CLASS: TEST BX, 0001H ;A和B都为奇数吗
JZ EXIT ;A和B同为偶数,转走
INC B
INC A
EXIT: RET
MAIN ENDP
CSEG ENDS ;以上定义代码段
;--------------------------------------------------------------------------
END START
22、 假设已编制好5个歌曲程序,它们的段地址和偏移地址存放在数据段的跳跃表SINGLIST中。试编制一程序,根据从键盘输入的歌曲编号1~5,转去执行五个歌曲程序中的某一个。
答:程序如下:
DSEG SEGMENT
SINGLIST DD SING1
DD SING2
DD SING3
DD SING4
DD SING5
ERRMSG DB ‘Error! Invalid parameter!’, 0DH, 0AH, ‘$’
DSEG ENDS
;--------------------------------------------------------------------------
CSEG SEGMENT
MAIN PROC FAR
ASSUME CS: CSEG, DS: DSEG
START: PUSH DS ;设置返回DOS
SUB AX, AX
PUSH AX
MOV AX, DSEG
MOV DS, AX ;给DS赋值
BEGIN: MOV AH, 1 ;从键盘输入的歌曲编号1~5
INT 21H
CMP AL, 0DH
JZ EXIT ;是回车符,则结束
SUB AL, ‘1’ ;是1~5吗
JB ERROR ;小于1,错误
CMP AL, 4
JA ERROR ;大于5,错误
MOV BX, OFFSET SINGLIST
MUL AX, 4 ;(AX)=(AL)*4,每个歌曲程序的首地址占4个字节
ADD BX, AX
JMP DWORD PTR[BX] ;转去执行歌曲程序
ERROR: MOV DX, OFFSET ERRMSG
MOV AH, 09H
INT 21H ;显示错误信息
JMP BEGIN
SING1: ┇
JMP BEGIN
SING2: ┇
JMP BEGIN
SING3: ┇
JMP BEGIN
SING4: ┇
JMP BEGIN
SING5: ┇
JMP BEGIN
EXIT: RET
MAIN ENDP
CSEG ENDS ;以上定义代码段
;--------------------------------------------------------------------------
END START