习题4汇编语言程序设计.docx
《习题4汇编语言程序设计.docx》由会员分享,可在线阅读,更多相关《习题4汇编语言程序设计.docx(23页珍藏版)》请在冰豆网上搜索。
习题4汇编语言程序设计
习题四汇编语言程序设计
主要内容:
汇编语言程序设计。
主要介绍汇编语言程序的设计方法与编程原理,重点掌握算术运算程序、字符串处理程序、码制转换程序、子程序设计程序、常用DOS和BIOS功能调用程序、汇编语言常用伪指令。
4.1分析执行下列指令序列后的结果:
1)MOVAX,1234H
MOVBX,00FFH
ANDAX,BX
【答】(AX)=0034H
2)MOVAL,01010101B
ANDAL,00011111B;(AL)=00010101B
ORAL,11000000B;(AL)=11010101B
XORAL,00001111B;(AL)=11011010B
NOTAL
【答】(AL)=00100101B
3)MOVDL,05H
MOVAX,0A00H
MOVDS,AX
MOVSI,0H
MOVCX,0FH
AGAIN:
INCSI
CMP[SI],DL
LOOPNEAGAIN
HLT
本程序实现了什么功能?
【答】在以0A001H开始的15个单元中查找05H。
4)MOVAX,DSEGADDR
MOVDS,AX
MOVES,AX
MOVSI,OFFSETB1ADDR
MOVDI,OFFSETB2ADDR
MOVCX,N
CLD
REPMOVSB
HLT
本程序实现了什么功能?
【答】将B1ADDR中N个字节数据传送到B2ADDR开始的15个存储单元。
5)MOVAX,0H
MOVDS,AX
MOVES,AX
MOVAL,05H
MOVDI,0A000H
MOVCX,0FH
CLD
AGAIN:
SCASB
LOOPNEAGAIN
HLT
本程序实现了什么功能?
【答】从地址0A000H开始的15个单元中查找字节型数据05H,用条件循环LOOPNZ,控制数据05H的查找。
4.2阅读程序:
1).CLD
LEADI,[0100H]
MOVCX,0080H
XORAX,AX
REPSTOSW
本程序实现了什么功能?
【答】将DS中起始地址为0100H的128个字节单元清零。
2).MOVAL,08H
SALAL,01H;(AL)=00010000H
MOVBL,AL
MOVCL,02H
SALAL,CL;(AL)=01000000H
ADDAL,BL;(AL)=01010000H
本程序实现了什么功能?
【答】将AL中的内容乘以10。
4.3试分析下列程序完成什么功能?
MOVDX,3F08H
MOVAH,0A2H
MOVCL,4
SHLDX,CL;(DX)=F080H
MOVBL,AH
SHLBL,CL;(BL)=20H
SHRBL,CL;(BL)=02H
ORDL,BL;(DL)=82H
【答】将DX中的低4位数据8H分离出来,将AH中的低4位数据2H分离出来,合并为82H存放在DL。
4.4已知程序段如下:
MOVAX,1234H
MOVCL,4
ROLAX,CL
DECAX
MOVCX,4
MULCX
试问:
(1)每条指令执行后,AX寄存器的内容是什么?
(2)每条指令执行后,CF,SF及ZF的值分别是什么?
(3)程序运行结束时,AX及DX寄存器的值为多少?
【答】MOVAX,1234H;(AX)=1234H,CF=SF=ZF=0
MOVCL,4
ROLAX,CL;(AX)=2341H,CF=1,SF=ZF=0
DECAX;(AX)=2340H,CF=1,SF=ZF=0
MOVCX,4;
MULCX;(AX)=8000H,CF=ZF=0,SF=1,DX=0
4.5试分析下列程序段:
ADDAX,BX
JNCL2
SUBAX,BX
JNCL3
JMPSHORTL5
如果AX、BX的内容给定如下:
AXBX
(1)14C6H80DCH(程序转向L2)
(2)B568H54B7H(程序转向SHORTL5)
问该程序在上述情况下执行后,程序转向何处?
【答】
(1)程序转向L2。
(2)程序转向SHORTL5。
4.6以下为某个数据段,试问各个变量分别占多少字节,该数据段共占多少字节?
DATASEGMENT
VAR1DW9;2字节
VAR2DD10DUP(?
),2;44字节
VAR3DB2DUP(?
,10DUP(?
));22字节
VAR4DB‘HOWAREYOU';11字节
DATAENDS
【答】该数据段共占79字节。
4.7下列语句在存储器中分别为变量分配多少字节空间?
并画出存储空间的分配图。
VAR1DB10,2;2字节
VAR2DW5DUP(?
),0;12字节
VAR3DB‘HOWAREYOU?
',‘$';13字节
VAR4DD-1,1,0;2字节
Var1
Var2
Var3
Var4
10
?
?
FFH
2
?
U
00H
?
O
00H
?
Y
00H
?
01H
?
E
00H
?
R
00H
?
A
00H
?
00H
?
W
00H
0
O
00H
0
H
00H
$
4.8编写一段程序,比较两个5字节的字符串OLDS和NEWS,若相同,在RESULT置0,否则置0FFH。
【答】参考程序:
DATASEGMENT
OLDSDB1,2,3,4,5
NEWSDB1,2,3,4,'A'
N=$-NEWS
RESULTDB0
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
START:
MOVAX,DATA
MOVDS,AX;初始化
MOVSI,OFFSETOLDS
MOVDI,OFFSETNEWS
MOVCX,N
DON:
MOVAL,[SI]
CMPAL,[DI]
JNZNOEQU;串不相等转
INCSI
INCDI
LOOPDON
MOVAL,0
JMPOUTPUT
NOEQU:
MOVAL,0FFH
OUTPUT:
MOVRESULT,AL
STOP:
JMPSTOP;程序陷阱
CODEENDS
ENDSTART
4.9编程求和Y=A1+A2+….+A100。
其中Ai为字节变量。
【答】参考程序:
DATASEGMENT
TABLEDW1111H,2222H,3333H,2222H
COUNTEQU$-TABLE
YALDW?
YAHDW?
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
MIANPROCFAR
PUSHDS
MOVAX,0
PUSHAX
MOVAX,DATA
MOVDS,AX
MOVDX,0
XORAX,AX;清AX
MOVBX,OFFSETTABLE
MOVCX,4
LP:
ADDAX,[BX];求和
ADCDX,0
INCBX
INCBX;指向下一个数
LOOPLP;未加完,继续
MOVYAL,AX;存和
MOVYAH,DX
MAINENDP
CODEENDS
ENDSTART
4.10内存中以FIRST和SECOND开始的单元中分别存放着两个16位组合的十进制(BCD码)数,低位在前。
编程序求这两个数的组合的十进制和,并存到以THIRD开始的单元。
【答】参考程序:
1325+9839=?
DATASEGMENT
FIRSTDB05H,02H,03H,01H;
SECONDDB09H,03H,08H,09H;
THIRDDB20DUP(?
)
DATAENDS
STACKSEGMENT
ST1DB100DUP(‘SA’)
TOP1EQU$-ST1
STACKENDS
CODESEGMENT
ASUMMECS:
CODE,DS:
DATA,SS:
STACK
MAINPROCFAR
START:
MOVAX,DAT;初始化数据段
MOVDS,AX
MOVAX,STACK;初始化堆栈段
MOVSS,AX
MOVAX,TOP1
MOVSP,AX
MOVCX,4;计算4次
MOVBX,OFFSETDAT1;取数据地址
MOVSI,OFFSETDAT2;取数据地址
MOVDI,OFFSETSUM;取结果地址
MOVAH,00H;将暂存标志的AH清0
DON1:
MOVAL,[BX];取第一个数
SAHF;将AH中的标志送标志寄存器
ADCAL,[DI];与第二个数带进位加
AAA;十进制校正
LAHF;将标志寄存器内容送AH
ORAL,30H;计算值拼成ASCII码
MOV[DI],AL;存结果的ASCII码
INCBX;指向第一个数的下一位
INCSI;指向第二个数的下一位
INCDI;指向结果单元的下一位
LOOPDON1;未计算完,继续
ANDAH,01H;将最高位的进位标志送AH
ORAH,30H;最高位的进位位拼成ASCII码
MOV[DI],AH;存结果的最高位
MOVAH,02H;调用DOS的02H功能显示
MOVCX,05H;显示数据的位数
DON2:
MOVDL,[DI];显示数据送DL
INT21H;显示
DECDI;显示数据所在存储单元加一
LOOPDON2;未显示完,继续
MOVAH,4CH;返回DOS
INT21H
RET
MAINENDP
CODEENDS
ENDSTART
4.11试编程序,统计由40000H开始的16K个单元中所存放的字符“A“的个数,并将结果存放在DX中。
【答】参考程序
DATASEGMENT
BUFDB'DFASFAAAFDFAAFFFA'
COUNTEQU$-BUF
DATAENDS
STACKSEGMENT
BUFFDW100DUP(?
)
MEQU$-STA
STACKENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA,SS:
STACK
BEGIN:
MOVAX,DATA
MOVDS,AX
MOVAX,STACK
MOVSS,AX
MOVAX,M
MOVSP,AX
MOVCX,COUNT
MOVDX,0
LEASI,BUF
MOVAL,'A'
CALLFindChar
MOVAH,4CH
INT21H;返回DOS
FindCharPROCNEAR
PUSHDX
NEXT:
CMP[SI],AL
JNZOTHER
INCDX
OTHER:
INCSI
LOOPNEXT
POPDX
RET
FindCharENDP
CODEENDS
ENDBEGIN
4.12统计数据块中正数与负数的个数,并将正数与负数分别送到两个缓冲区。
【答】解法一:
采用串操作指令,要程序片段:
BLOCKDB-1,-3,5,6,-2,0,20,10
PLUS_DDB8DUP(?
);正数缓冲区
MINUS_DDB8DUP(?
);负数缓冲区
PLUSDB0
MINUSDB0
MOVSI,OFFSETBLOCK
MOVDI,OFFSETPLUS_D
MOVBX,OFFSETMINUS_D
MOVCX,8;数据个数送CX
GOON:
LODSB;AL←[SI]
TESTAX,80H
JNZJMIUS;为负数,转
INCPLUS;正数个数加一
STOSB;[DI]←AL,传正数
JMPAGAIN
JMIUS:
INCMINUS;负数个数加一
XCHGBX,DI
STOSB;送负数到缓冲区
XCHGBX,DI
AGAIN:
DECCX
JNZGOON
解法二:
用比较指令CMP、转移指令JA/JNA/JB/JNB、循环指令LOOP等
BLOCKDB-1,-3,5,6,-2,0,20,10
NEQU$-BLOCK
PLUS_DDB8DUP(?
);正数缓冲区
PLUSDB0
MINUS_DDB8DUP(?
);负数缓冲区
MINUSDB0
……
MOVSI,OFFSETBLOCK
MOVDI,OFFSETPLUS_D
MOVBX,OFFSETMINUS_D
MOVCX,N;数据个数送CX
GOON:
MOVAL,[SI]
TESTAL,80H
JNZJMIUS;为负数,转
INCPLUS;正数个数加一
MOV[DI],AL;传正数
INCDI
JMPAGAIN
JMIUS:
INCMINUS;负数个数加一
MOV[BX],AL
INCBX
AGAIN:
INCSI
DECCX
JNZGOON
4.13编写一个子程序将AX中的十六进制数,转换成ASCII码,存于ADR开始的四个单元中。
提示:
1)、AX中的数从左到右,转换成ASCII码,用循环左移ROL和AND指令,把提出的一个十六进制数置BL中;
2)、0~9的ASCII码:
30~39H,A~F的ASCII码:
41H~46H。
(先把每个数加30H,判断是否为数字0~9?
若是A~F,再加07H,得字母的ASCII码。
)
【答】参考程序:
DATASEGMENT
ADRDB5DUP(?
)
DATAENDS
CODESEGMENT
MAINPROCFAR
ASSUMECS:
CODE,DS:
DATA
START:
MOVAX,7EC3H;假设ax中存放7ec3h
LEASI,ADR
MOVDL,4
AGAIN:
MOVBX,AX
ANDBX,000FH
ADDBL,30H
CMPBL,'9'
JGADUST
JMPSTORE
ADUST:
ADDBL,07H
STORE:
MOV[SI],BL
INCSI
MOVCL,4
ROLAX,CL
DECDL
JNZAGAIN
MAINENDP
CODEENDS
ENDSTART
4.14编写一个子程序将AX中的2进制数,转换成10进制ASCII码,存于ADR开始的五个单元中。
【答】算法分析:
(1)一个16位2进制数,其值最大为65535。
采用除10取余数方法,即可得到各个位。
A)十进制数a5a4a3a2a1,除以10,余数a1为个位;商a5a4a3a2
B)a5a4a3a2再除以10,余数a2为十位;
C)以此类推,得到百位、千位、万位。
(2)再将其加上30H则得到ASCII码,以便输出显示。
(3)若数据为负数,用0减去该数,可得绝对值,再将符号位记录下来即可。
参考程序:
DATASEGMENT
BINDW-1988;带符号二进制数
ADRDB6DUP(0),'$';十进制数以ASCII码存储
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
TRANPROCFAR
MOVAX,DATA
MOVDS,AX
MOVAX,BIN
LEADI,ADR
CALLBINASCII;十六位二进制数转换为十进制ascii码
MOVAH,4CH
INT21H;返回DOS
TRANENDP
;子程序BINASCII功能:
将16位二进制数转换为ASCII码,存于ADR开始的连续6个单元,并显示
;入口参数:
AX=待转换的数,预定义一个缓存区ADR,7个字节,最末字节为‘$’字符。
;出口参数:
DI=转换好的ASCII码首地址,显示该十进制数据
BINASCIIPROC
PUSHBX
PUSHCX
PUSHDX
TESTAX,8000H;判断数据的符号
JNSPLUS
MINUS:
MOVBYTEPTR[DI],'-';将符号存储
NEGAX;如是负数,取相反数去掉符号位
JMPGO
PLUS:
MOVBYTEPTR[DI],'+';将符号码存储
GO:
ADDDI,5;DI指向个位
MOVCX,5
MOVBX,10
LP:
MOVDX,0
DIVBX;算法为a/10,余数为一个低位十进制数
ADDDL,30H;转换为ASCII码
MOVBYTEPTR[DI],DL;从个位开始存储
DECDI
LOOPLP
MOVDX,DI
MOVAH,09H
INT21H;显示
POPDX
POPCX
POPBX
RET
BINASCIIENDP
CODEENDS
ENDTRAN
4.15编写一个子程序,对AL中的数据进行偶校验,并将经过校验的结果放回AL中。
【答】参考程序:
JIAOYANPROCFAR
MOVAL,1001110B
ORAL,AL
JNPNEXT
MOVAL,0
JMPDONE
NEXT:
MOVAL,1
DONE:
MOVAH,04CH
INT21H
JIAOYANENDP
4.16从2000H单元开始的区域,存放100个字节的字符串,其中有几个$符号(ASCII码为24),找出第一个$符号,送AL中,地址送BX。
【答】参考程序:
SEARCHPROCFAR
MOVDI,2000H
MOVCX,100
MOVAL,24H
CLD
REPNZSCASB
JNZSTOP
DECDI
MOVBX,DI
MOVAL,[DI]
STOP:
RET
SEARCHENDP
4.17用串操作指令实现:
先将100H个数从2170H单元处搬到1000H单元处,然后从中检索等于AL中字符的单元,并将此单元换成空格字符。
【答】参考程序:
MOVAL,24H
MOVSI,2170H
MOVDI,1000H
MOVCX,100H
CLD
DO:
REPMOVSB
MOVDI,1000H
MOVCX,100H
CLD
REPNZSCASB
DECDI
MOV[DI],20H
INCDI
CMPCX,0
JNZDO
HLT
4.18从60H个元素中寻找一个最大的值,并放到AL中,假设这60个元素放在BUF开始的单元中。
【答】参考程序:
DATASEGMENT
BUFDB0,1,2,3,4,5,6,7,8,9;
DATAENDS
STACKSEGMENT
STADB20DUP(?
)
TOPEQU$-STA
STACKENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA,SS:
STACK
START:
MOVAX,DATA
MOVDS,AX
MOVAX,STACK
MOVSS,AX
MOVAX,TOP
MOVSP,AX
MOVCX,10
MOVAL,0
LEABX,BUF
AGAIN:
CMPAL,[BX]
JGENEXT;大于等于转移
MOVAL,[BX]
NEXT:
INCBX
LOOPAGAIN
MOVAH,4CH
INT21H
CODEENDS
ENDSTART
4.19排序程序设计:
把表中元素按值的大小升序排列。
要求显示排序前和排序后的数据。
【答】参考程序:
DATASEGMENT
TABDB'8095554'
N=$-TAB
OKDB0DH,0AH,'OK!
$'
DATAENDS
STACKSEGMENT
STADB20DUP(?
)
TOPEQU$-STA
STACKENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA,SS:
STACK
STAR:
MOVAX,DATA
MOVDS,AX;初始化数据段
MOVAX,STACK
MOVSS,AX
MOVAX,TOP
MOVSP,AX
CALLARRAY
DO:
MOVAH,4CH
INT21H;返回DOS
ARRAYPROCNEAR
PUSHAX
PUSHBX
PUSHCX
PUSHDX
MOVDL,N