第四章汇编语言源程序设计.docx
《第四章汇编语言源程序设计.docx》由会员分享,可在线阅读,更多相关《第四章汇编语言源程序设计.docx(23页珍藏版)》请在冰豆网上搜索。
第四章汇编语言源程序设计
第四章汇编语言源程序设计
1.画出数据段汇编后相应存储单元中的内容并标出存储单元的逻辑地址。
DATASEGMENT
ORG0100H
ABC0EQU78H
ABCDB09H,-2,45H,2DUP(01H,?
),‘AB’
ABC1DW-2,34H+ABC0,$
ABC2DD12H
ABC3DWABC
DATAENDS
解:
DS:
0100H
ABC→
09H
DS:
0101H
FEH
DS:
0102H
45H
DS:
0103H
01H
DS:
0104H
-
DS:
0105H
01H
DS:
0106H
-
DS:
0107H
41H
DS:
0108H
42H
DS:
0109H
ABC1→
FEH
DS:
010AH
FFH
DS:
010BH
ACH
DS:
010CH
00H
DS:
010DH
0DH
DS:
010EH
01H
DS:
010FH
ABC2→
12H
DS:
0110H
00H
DS:
0111H
00H
DS:
0112H
00H
DS:
0113H
ABC3→
00H
DS:
0114H
01H
2.设程序中的数据定义如下:
PARTNODW?
PNAMEDB16DUP(?
)
COUNTDD?
PLENTHEQU$-PARTNO
问PLENTH的值为多少?
它的含义是什么?
解:
PLENTH的值为22(16H)。
表示当前位置与PARTNO之间有22个字节空间。
3.假设程序中的数据定义如下:
LNAMEDB30DUP(?
)
ADDRESSDB30DUP(?
)
CITYDB15DUP(?
)
CODE_LISTDB1,7,8,3,2
(1)用一条MOV指令将LNAME的偏移地址放入AX;
(2)用一条指令将CODE_LIST的头两个字节的内容放入SI:
(3)写一条伪操作使CODE_LENGTH的值等于CODE_LIST域的实际长度。
解:
(1)MOVAX,OFFSETLNAME
(2)MOVSI,WORDCODE_LIST
(3)CODE_LENGTHEQU$-CODE_LIST
4.执行下列程序段后,AX、BX的内容各是什么?
MOVAX,0001H
MOVBX,8000H
NEGAX
MOVCX,4
AA:
SHLAX,1
RCLBX,1
LOOPAA
HLT
解:
AX=0FFF0H,BX=000FH
5.阅读以下程序,回答问题
DATASEGMENT
ABCDB90H,12H,43H,56H,04H,01H
COUNTEQU$-ABC
RESULTDW?
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
START:
PUSHDS
MOVAX,DATA
MOVDS,AX
XORAX,AX
MOVCX,COUNT
LEASI,ABC
LEADI,RESULT
AA:
MOVBL,[SI]
INCSI
CMPBL,80H
JCNEXT1
NEGBL
NEXT1:
ADDAL,BL
ADCAH,00H
LOOPAA
MOV[DI],AX
MOVAH,4CH
INT21H
CODEENDS
ENDSTART
(1)程序完成什么功能?
(2)程序中NEGBL指令的作用是什么?
(3)程序执行结束后RESULT字单元的内容是什么?
(4)能否用MOVSI,OFFSETABC代替程序中LEASI,ABC指令?
(5)汇编结束后符号COUNT的值是什么?
解:
(1)程序完成求一组有符号字节数的绝对值之和。
(2)程序中NEGBL指令的作用是求负数的绝对值。
(3)程序执行结束后RESULT字单元的内容是0120H。
(4)能。
(5)汇编结束后符号COUNT的值是06H。
6.阅读以下程序,回答问题
DSEGSEGMENT
ARRAYDB34H,56H,23H,70H,96H
COUNTEQU$-ARRAY
DSEGENDS
SSEGSEGMENTPARASTACK‘STACK’
DB256DUP(0)
SSEGENDS
CSEGSEGMENT
ASSUMECS:
CSEG,DS:
DSEG,SS:
SSEG
START:
MOVAX,DSEG
MOVDS,AX
MOVSI,OFFSETARRAY
MOVCX,COUNT
CLD
NEXT:
LODSB
MOVBL,AL
ANDAL,0F0H
PUSHCX
MOVCL,4
SHRAL,CL
ORAL,30H
CALLDISP
MOVAL,BL
ANDAL,0FH
ORAL,30H
CALLDISP
DECCX
JCXZDONE
MOVAL,2CH;逗号的ASCII码为2CH
CALLDISP
JMPNEXT
DONE:
MOVAH,4CH;终止当前进程,返回调用进程
INT21H
DISPPROCNEAR
MOVAH,14;写字符到当前光标位置,光标前进一格
INT10H
RET
DISPENDP
CSEGENDS
ENDSTART
(1)程序执行结束后,屏幕上显示的内容是什么?
(2)程序中带下划线的指令可以用什么指令替代(仅一条)?
(3)程序中空格处应填入什么指令,才能保证程序按要求正常执行?
解:
(1)程序执行结束后,屏幕上显示的内容是34,56,23,70,96。
(2)程序中带下划线的指令可以用LEASI,ARRAY指令替代。
(3)程序中空格处应填入POPCX指令,才能保证程序按要求正常执行。
7.AX寄存器中存有4位压缩BCD码,试编写程序将这4位数字分开,并分别存入BH、BL、CH和CL寄存器中。
解:
参考程序段如下:
……
MOVDX,AX
MOVCL,04H
ROLAX,CL
ANDDX,0F0FH
MOVBL,DH
MOVCL,DL
ANDAX,0F0FH
MOVBH,AL
MOVCH,AH
……
8.已知X、Y是字节型的无符号整数,编写程序计算
。
解:
参考程序如下:
DATASEGMENT
XDB?
;运行程序时取X分别位于两个分支
YDB?
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
START:
MOVAX,DATA
MOVDS,AX
MOVAL,X
CMPAL,20
JNCNEXT
MOVCL,03H
SHRAL,CL
JMPNEXT1
NEXT:
SUBAL,15
NEXT1:
MOVY,AL
MOVAH,4CH
INT21H
CODEENDS
ENDSTART
9.编写程序,统计寄存器BX中二进制位“1”的个数,结果存在AL中。
解:
参考程序如下:
CODESEGMENT
ASSUMECS:
CODE
START:
MOVAL,00H
MOVDX,BX
MOVCX,16
AA:
CMPDX,0
JZNEXT
SHLDX,1
JNCNEXT1
INCAL
NEXT1:
LOOPAA
NEXT:
MOVAH,4CH
INT21H
CODEENDS
ENDSTART
10.编写程序段将计算机日期设置为2009年10月1日。
解:
参考程序段如下:
MOVCX,2009H;设置年
MOVDH,10H;设置月
MOVDL,01H;设置日
MOVAH,2BH
INT21H
HLT
11.编写程序实现接收一个字符的输入,并在屏幕上用二进制形式(0/1)显示出它的ASCII码值。
解:
参考程序如下:
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
START:
MOVAH,01H;键盘输入
INT21H
MOVBL,AL
MOVCX,0007H
SHLBL,1
AA:
SHLBL,1
JCNEXT1
MOVDL,’0’
JMPNEXT
NEXT1:
MOVDL,’1’
NEXT:
MOVAH,02H;显示输出7位ASCII码值
INT21H
LOOPAA
MOVAH,4CH
INT21H
CODEENDS
ENDSTART
12.设数据块存放在BUFFER开始的50个字节单元中,试编写程序统计数据块中正数(不包括0)的个数,并将统计的结果存放到NUMBER单元中。
解:
参考程序如下:
DATASEGMENT
BUFFERDB23H,00H,56H,89H,09H,30H
DB98H,11H,07H,…
COUNTEQU$-BUFFER
NUMBERDB00H
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
START:
MOVAX,DATA
MOVDS,AX
MOVCX,COUNT
LEASI,BUFFER
AA:
MOVAL,[SI]
CMPAL,00H
JZNEXT
JSNEXT
INCNUMBER
NEXT:
INCSI
LOOPAA
MOVAH,4CH
INT21H
CODEENDS
ENDSTART
13.内存的一个区域中有100个字符是用小写字母表示的,试编写一个程序,把它们转换成大写字母,并送屏幕显示。
解:
参考程序如下:
DATASEGMENT
ABCDB61H,65H,62H,63H,…;(100个小写字母)
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
START:
MOVAX,DATA
MOVDS,AX
MOVCX,0064H
LEASI,ABC
AA:
MOVDL,[SI]
SUBDL,20H
MOV[SI],DL
MOVAH,02H
INT21H
INCSI
LOOPAA
MOVAH,4CH
INT21H
CODEENDS
ENDSTART
14.“9876”是将输入数据字符“3268”通过密码表“3589027164”加密而得,编写解密程序,求任意输入四位密码的原码。
解:
参考程序如下:
DATASEGMENT
ABCDB33H,35H,38H,39H,30H
DB32H,37H,31H,36H,34H
ABC1DB4DUP(00H)
ABC2DB00H
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
START:
MOVAX,DATA
MOVDS,AX
LEASI,ABC1
LEADI,ABC2
MOVCX,0004H
AA:
MOVAH,01H
INT21H
MOV[SI],AL
INCSI
LOOPAA
LEASI,ABC1
MOVDX,0000H
MOVCX,0004H
AA0:
LEABX,ABC
AA1:
MOVAL,[SI]
CMPAL,[BX]
JZNEXT
INCBX
INCDL
JMPAA1
NEXT:
PUSHCX
CMPCX,01H
JZNEXT1
MOVCL,04H
SHLDX,CL
NEXT1:
POPCX
LOOPAA0
MOV[DI],AX
MOVAH,4CH
INT21H
CODEENDS
ENDSTART
15.在STRING单元开始存放着一字符串,字符串以“$”结束,试编制一程序测试该字符串中是否有数字0~9,如有则将CL中的第5位置1,否则将该位清0。
解:
参考程序如下:
DATASEGMENT
ABCDB‘ABCDS9KL$’
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
START:
MOVAX,DATA
MOVDS,AX
LEASI,ABC
MOVCL,00H
AA:
MOVAL,[SI]
CMPAL,’$’
JZNEXT1
CMPAL,30H
JCNEXT
CMPAL,3AH
JNCNEXT
ORCL,20H
JMPNEXT1
NEXT:
INCSI
JMPAA
NEXT1:
MOVAH,4CH
INT21H
CODEENDS
ENDSTART
16.编写程序完成把DX中的16进制数转换为ASCII码,并将对应的ASCII码依次存入MEM开始的存储单元中。
例如,当DX的内容为2A49H时,程序执行结束后,MEM单元开始的4个字节的内容依次为39H,34H,41H,32H。
解:
DATASEGMENT
MEMDB4DUP(?
)
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
START:
MOVAX,DATA
MOVDS,AX
MOVCH,04H
MOVBX,OFFSETMEM
MOVCL,04H
AA1:
MOVAX,DX
ANDAL,0FH
ADDAL,30H
CMPAL,3AH
JCNEXT
ADDAL,07H
NEXT:
MOV[BX],AL
INCBX
RORDX,CL
DECCH
JNZAA1
MOVAH,4CH
INT21H
CODEENDS
ENDSTART
17.现有一个以“$”结尾的字符串,编写程序完成剔除字符串中的空格字符。
解:
参考程序如下:
DATASEGMENT
ABCDB‘ABCDS9KL$’
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
START:
MOVAX,DATA
MOVDS,AX
LEASI,ABC
MOVBX,SI
AA:
MOVAL,[SI]
CMPAL,’$’
JZNEXT
CMPAL,20H;空格的ASCII码值为20H
JZNEXT1
MOVAL,[SI]
MOV[BX],AL
INCSI
INCBX
JMPAA
NEXT1:
INCSI
JMPAA
NEXT:
MOVAH,4CH
INT21H
CODEENDS
ENDSTART
18.编一程序,在STRING开头的数据区中查找WE字符串,数据区以$符作为结束符号。
如查到,给出HAVEFOUND提示;如查不到,给出NOTFOUND提示。
解:
参考程序如下:
DATASEGMENT
STRINGDB‘ABCWE5$’
REDB‘NOTFOUND$’
RE1DB‘HAVEFOUND$’
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
BEGIN:
MOVAX,DATA
MOVDS,AX
LEASI,STRING
AA:
MOVAL,[SI]
CMPAL,’$’
JZNEXT
CMPAL,’W’
JNZNEXT1
INCSI
MOVAL,[SI]
CMPAL,’E’
JNZAA
LEADX,RE1
JMPNEXT2
NEXT1:
INCSI
JMPAA
NEXT:
LEADX,RE
NEXT2:
MOVAH,09H
INT21H
MOVAH,4CH
INT21H
CODEENDS
ENDBEGIN
19.设在A、B和C单元中分别存放着三个数,若三个数都不是0,则求出三数之和并存放在D单元中;若三个数中有一个为0,则把其余两个单元也清0。
试编写此程序。
解:
参考程序如下:
DATASEGMENT
ADB?
BDB?
CDB?
;程序运行前修改A、B和C单元的内容
DDB?
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
START:
MOVAX,DATA
MOVDS,AX
MOVAL,A
CMPAL,00H
JZNEXT
MOVAL,B
CMPAL,00H
JZNEXT
MOVAL,C
CMPAL,00H
JZNEXT
MOVAL,A
ADDAL,B
ADDAL,C
MOVD,AL
JMPNEXT1
NEXT:
MOVA,00H
MOVB,00H
MOVC,00H
NEXT1:
MOVAH,4CH
INT21H
CODEENDS
ENDSTART
20.在以DA1为首地址的内存中有50个无符号字节数,编写程序统计其中素数的个数,结果以十进制形式在屏幕上显示。
要求分别用子程序完成素数个数统计及十进制数显示。
解:
分析:
素数,又称质数,是这样的整数:
它除了能表示为它自己和1的乘积以外,不能表示为任何其他两个整数的乘积。
判断一个整数是否为素数的方法:
用这个数除以2到它本身,如果只能被它本身整除则为素数。
参考程序如下:
DATASEGMENT
ttldb'Totalnumberofprimenumber(s):
$'
tendw10
pcountdb0
da1dB1,2,3,4,5,6,7,8,9,10
dB11,12,13,14,15,16,17,18,19,20
dB21,22,23,24,25,26,27,28,29,30
dB31,32,33,34,35,36,37,38,39,40
dB41,42,43,44,45,46,47,48,49,50
DATAENDS
CODESEGMENT
ASSUMECS:
CODE,DS:
DATA
main:
movax,data
movds,ax
leasi,da1
movdi,50;用di做主循环计数器
cld
m_1:
lodsb;从ds:
si取一个无符号整数到ax
callisprime
jncm_2
incpcount
callprintax;是素数则输出ax里的十进制数
movdl,9;用制表符分隔
callputc
m_2:
decdi
jnzm_1;50个数完成?
movdx,offsetttl;输出素数总数
callputs
moval,pcount;输出素数总数
xorah,ah
callprintax
movah,4ch
int21h
isprimeproc
cbw
testax,1;是否为偶数
jnzip_1;若是偶数直接返回
ip_0:
clc;CF=0表示是合数
ret
ip_1:
cmpax,1;1或0?
jbeip_0;不是素数
cmpax,3
jeip_4;3是素数直接返回
movcx,3;从3开始循环
ip_2:
movbx,ax;留个副本在bx里
xordx,dx;为除法清除dx
divcx
movax,bx;恢复ax里的数
ordx,dx;余数为0否
jzip_0;为0为合数
addcx,3;本来是除数加2,只尝试除数为奇数的情况即可,直接加3是为了比较cx是否以及到了ax-1
cmpcx,ax
jbip_3;若cx高于或等于ax,说明除数已经尝试到了n-1,ax是素数,直接返回,否则继续到ip_3
ip_4:
stc;CF=1表示是素数
ret
ip_3:
deccx;cx-1才是真正下个要尝试的除数
jmpip_2;继续试
isprimeendp
putsproc
movah,9
int21h
ret
putsendp
putcproc
movah,2
int21h
ret
putcendp
printaxproc
xordx,dx
divten
movcx,ax
orcx,dx;若商与余数都为0则结束递归
jzp_1
pushdx;留存DX中的余数以在递归后输出
callprintax;递归
popdx;从最高位开始恢复余数
adddl,'0';原来的输出语句add一下就好了
callputc
p_1:
ret
printaxendp
CODEENDS
endmain