348213311.doc - 20 - 作者:张兆印
答:程序如下:
D_SEG SEGMENT AUGW LABEL WORD AUGEND DD 99251 SUM DD ? D_SEG ENDS ;以上定义数据段 ;---------------------------------------------------------------- E_SEG SEGMENT ADDW LABEL WORD ADDEND DD -15962 E_SEG ENDS ;以上定义附加段 ;---------------------------------------------------------------- C_SEG SEGMENT MAIN PROC FAR
ASSUME CS: C_SEG, DS: D_SEG, ES: E_SEG
START: PUSH DS ;设置返回DOS
SUB AX, AX PUSH AX
MOV AX, D_SEG MOV DS, AX ;给DS赋值 MOV AX, E_SEG MOV ES, AX ;给ES赋值
;
MOV AX, AUGW ;以下6条指令进行加法计算 MOV BX, AUGW+2 ADD AX, ES: ADDW ADC BX, ES: ADDW+2 ;不考虑有符号数溢出 MOV WORD PTR SUM, AX MOV WORD PTR [SUM+2], BX RET
MAIN ENDP C_SEG ENDS ;以上定义代码段 ;----------------------------------------------------------------
END START
4.18 请说明表示程序结束的微操作和结束程序执行的语句之间的差别。它们在源程序中应如何表示?
答:表示程序结束的微操作是指示汇编程序MASM结束汇编的标志,在源程序中用END表示;
结束程序执行的语句是结束程序运行而返回操作系统的指令,在源程序中有多种表示方法,比如INT 20H或MOV AX, 4C00H INT 21H以及RET等。 4.19 试说明下述指令中哪些需要加上PTR操作符:
BVAL DB 10H,20H WVAL DW 1000H
(1) MOV AL,BVAL ;不需要 (2) MOV DL,[BX] ;不需要 (3) SUB [BX],2 ;需要,如SUB BYTE PTR [BX],2 (4) MOV CL,WVAL ;需要,如MOV CL,BYTE PTR WVAL (5) ADD AL,BVAL+1 ;不需要 答:见注释。
第 五 章. 习 题
5.1 试编写一个汇编语言程序,要求对键盘输入的小写字母用大写字母显示出来。
答:程序段如下:
BEGIN: MOV AH, 1 ;从键盘输入一个字符的DOS调用
INT 21H
348213311.doc - 21 - 作者:张兆印
STOP:
CMP JB CMP JA SUB MOV MOV INT JMP RET
AL, ‘a’ STOP AL, ‘z’ STOP AL, 20H DL, AL AH, 2 21H BEGIN
;输入字符<‘a’吗? ;输入字符>‘z’吗?
;转换为大写字母,用AND AL, 1101 1111B也可 ;显示一个字符的DOS调用
5.2 编写程序,从键盘接收一个小写字母,然后找出它的前导字符和后续字符,再按顺序显示这三个
字符。
答:程序段如下:
BEGIN: MOV AH, 1 ;从键盘输入一个字符的DOS调用
INT 21H CMP AL, ‘a’ ;输入字符<‘a’吗? JB STOP CMP AL, ‘z’ ;输入字符>‘z’吗? JA STOP DEC AL ;得到前导字符 MOV DL, AL ;准备显示三个字符 MOV CX, 3
DISPLAY: MOV AH, 2 ;显示一个字符的DOS调用
INT 21H INC DL
LOOP DISPLAY
STOP: RET 5.3 将AX寄存器中的16位数分成4组,每组4位,然后把这四组数分别放在AL、BL、CL和DL中。
答:程序段如下:
DSEG SEGMENT STORE DB 4 DUP (?) DSEG ENDS
┇
BEGIN: MOV CL, 4 ;右移四次
MOV CH, 4 ;循环四次 LEA BX, STORE
A10: MOV DX, AX
AND DX, 0FH ;取AX的低四位 MOV [BX], DL ;低四位存入STORE中 INC BX SHR AX, CL ;右移四次 DEC CH JNZ A10 ;循环四次完了码?
B10: MOV DL, STORE ;四组数分别放在AL、BL、CL和DL中
MOV CL, STORE+1 MOV BL, STORE+2 MOV AL, STORE+3
STOP: RET 5.4 试编写一程序,要求比较两个字符串STRING1和STRING2所含字符是否完全相同,若相同则显示?MATCH?, 若不相同则显示?NO MATCH?。 答:程序如下:
DSEG SEGMENT
STRING1 DB ?I am a student.? STRING2 DB ?I am a student!?
348213311.doc - 22 - 作者:张兆印
YES DB ?MATCH?, 0DH, 0AH, ?$? NO DB ?NO MATCH?, 0DH, 0AH, ?$? 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: LEA SI, STRING1 ;设置串比较指令的初值
LEA DI, STRING2 CLD
MOV CX, STRING2 - STRING1 REPE CMPSB ;串比较 JNE DISPNO LEA DX, YES ;显示MATCH JMP DISPLAY
DISPNO: LEA DX, NO ;显示NO MATCH DISPLAY: MOV AH, 9 ;显示一个字符串的DOS调用
INT 21H RET
MAIN ENDP CSEG ENDS ;以上定义代码段 ;--------------------------------------------------------------------------
END START
5.5 试编写一程序,要求能从键盘接收一个个位数N,然后响铃N次(响铃的ASCII码为07)。
答:程序段如下:
BEGIN: MOV AH, 1 ;从键盘输入一个字符的DOS调用
INT 21H SUB AL, ?0? JB STOP ;输入字符0?吗? CMP AL, 9 ;输入字符>?9?吗? JA STOP CBW
MOV CX, AX ;响铃次数N JCXZ STOP
BELL: MOV DL, 07H ;准备响铃
MOV AH, 2 ;显示一个字符的DOS调用,实际为响铃 INT 21H
CALL DELAY100ms ;延时100ms LOOP BELL
STOP: RET 5.6 编写程序,将一个包含有20个数据的数组M分成两个数组:正数数组P和负数数组N,并分别把这两个数组中数据的个数显示出来。 答:程序如下:
DSEG SEGMENT COUNT EQU 20 ARRAY DW 20 DUP (?) ;存放数组 COUNT1 DB 0 ;存放正数的个数 ARRAY1 DW 20 DUP (?) ;存放正数
348213311.doc - 23 - 作者:张兆印
COUNT2 DB 0 ;存放负数的个数 ARRAY2 DW 20 DUP (?) ;存放负数 ZHEN DB 0DH, 0AH, ?The positive number is:?, ?$? ;正数的个数是: FU DB 0DH, 0AH, ?The negative number is:?, ?$? ;负数的个数是: 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 CX, COUNT
LEA BX, ARRAY LEA SI, ARRAY1 LEA DI, ARRAY2
BEGIN1: MOV AX, [BX]
CMP AX, 0 ;是负数码? JS FUSHU MOV [SI], AX ;是正数,存入正数数组 INC COUNT1 ;正数个数+1 ADD SI, 2 JMP SHORT NEXT
FUSHU: MOV [DI], AX ;是负数,存入负数数组
INC COUNT2 ;负数个数+1 ADD DI, 2
NEXT: ADD BX, 2
LOOP BEGIN1 LEA DX, ZHEN ;显示正数个数 MOV AL, COUNT1 CALL DISPLAY ;调显示子程序 LEA DX, FU ;显示负数个数 MOV AL, COUNT2 CALL DISPLAY ;调显示子程序 RET
MAIN ENDP
;-------------------------------------------------------------------------- DISPLAY PROC NEAR ;显示子程序
MOV AH, 9 ;显示一个字符串的DOS调用 INT 21H AAM ;将(AL)中的二进制数转换为二个非压缩BCD码 ADD AH, ?0? ;变为0~9的ASCII码 MOV DL, AH MOV AH, 2 ;显示一个字符的DOS调用 INT 21H ADD AL, ?0? ;变为0~9的ASCII码 MOV DL, AL MOV AH, 2 ;显示一个字符的DOS调用 INT 21H LEA DX, CRLF ;显示回车换行 MOV AH, 9 ;显示一个字符串的DOS调用 INT 21H
348213311.doc - 24 - 作者:张兆印
RET
DISPLAY ENDP ;显示子程序结束 CSEG ENDS ;以上定义代码段 ;--------------------------------------------------------------------------
END START
5.7 试编写一个汇编语言程序,求出首地址为DATA的100D字数组中的最小偶数,并把它存放在AX
中。
答:程序段如下:
BEGIN: MOV BX, 0
MOV CX, 100
COMPARE: MOV AX, DATA[BX] ;取数组的第一个偶数
ADD BX, 2 TEST AX, 01H ;是偶数吗? LOOPNZ COMPARE ;不是,比较下一个数 JNZ STOP ;没有偶数,退出 JCXZ STOP ;最后一个数是偶数,即为最小偶数,退出
COMPARE1: MOV DX, DATA[BX] ;取数组的下一个偶数
ADD BX, 2 TEST DX, 01H ;是偶数吗? JNZ NEXT ;不是,比较下一个数 CMP AX, DX ;(AX)<(DX)吗? JLE NEXT MOV AX, DX ;(AX)<(DX),则置换(AX)为最小偶数
NEXT: LOOP COMPARE1 STOP: RET 5.8 把AX中存放的16位二进制数K看作是8个二进制的“四分之一字节”。试编写程序要求数一下值为3(即11B)的四分之一字节数,并将该数(即11B的个数)在终端上显示出来。 答:程序段如下:
BEGIN: MOV DL, 0 ;计数初始值
MOV CX, 8
COMPARE: TEST AX, 03H ;是数03吗?
JNZ NOEQUAL ;不是,转走 INC DL ;是,计数
NOEQUAL: ROR AX, 1 ;准备判断下一个数
ROR AX, 1
LOOP COMPARE ADD DL, ?0? ;将计数值转换为ASCII码 MOV AH, 2 ;进行显示 INT 21H
STOP: RET 5.9 试编写一个汇编语言程序,要求从键盘接收一个四位的16进制数,并在终端上显示与它等值的二进制数。
答:程序段如下:
BEGIN: MOV BX, 0 ;用于存放四位的16进制数
MOV CH, 4 MOV CL, 4
INPUT: SHL BX, CL ;将前面输入的数左移4位
MOV AH, 1 ;从键盘取数 INT 21H CMP AL, 30H ;<0吗? JB INPUT ;不是‘0~F’的数重新输入 CMP AL, 39H ;是‘0~9’吗? JA AF ;不是,转‘A~F’的处理 AND AL, 0FH ;转换为:0000B~1001B