后续指令应为什么?
若视为二个无符号数比较大小,后续指令应为什么?
带符号数:
JLL1,无符号数:
JBL1
3.5ADD指令和ADC指令在什么情况下是一样的结果?
CF=0
3.6说出CALL指令和INT21H指令的操作,有何异同?
CALL把断点压入堆栈,不一定是远调,INT21H还要把FLAGS压入堆栈,且是远调,总入口地址为84H内存中的两个字。
3.7除了用4CH号系统功能调用结束程序的执行并退出,还有哪些办法?
RET指令,INT20H
3.8指出下列错误的指令,说出错误原因,并给出合适的修改。
(1)MOVAX,[DX]/MOVAX,[BX]
(2)MOVDS,DATA/MOVDS,BX
(3)MOVCS,AX/MOVES,AX
(4)MOVAX,DL/MOVAL,DL
(5)PUSHAL/PUSHAX
(6)ADD[BX],[DI]/ADD[BX],DI
(7)LEA[BX],[2000H]/LEABX,[2000H]
(8)MOV[BX],OFFSET[2000H]
(9)MOV[SI],2/MOVBYTEPTR[SI],2
(10)MULBX,CX/MULBX
(11)DIV5/DIVBX
(12)MOVBYTE[SI],2/MOVBYTEPTR[SI],2
(13)MOVAX,[SI+DI]/MOVAX,[BX+SI]
(14)SHRAX,4/SHRAX,1
(15)CMP6,AX/CMPAX,6
(16)MOV[FFFF],AX/MOV[FFFE],AX
(17)MOVAX,BX+4/MOVAX,[BX+4]
(18)JMPFARPRO/JMPFARPTRPRO
3.9假定(DS)=1200H,(SS)=4400H,(BX)=463DH,(BP)=2006H,(SI)=6A00H,位移量D=4524H,以AX寄存器为目的操作数,试写出以下各种寻址方式下的传送指令,并确定源操作数的有效地址EA和物理地址。
(1)立即寻址;操作数的EA就是指令的EA/操作数在指令中/无EA
(2)直接寻址;EA=4524H,物理地址=DS:
4524
(3)使用BX的寄存器寻址;无EA
(4)使用BX的间接寻址;EA=463DH,物理地址=DS:
463D
(5)使用BP的寄存器相对寻址;MOVAX,[BP+4524],EA=2006+4524,
物理地址=SS:
EA
(6)基址变址寻址;MOVAX,[BX+SI],EA=BX+SI,物理地址=DS:
EA
(7)相对基址变址寻址;MOVAX,[4524+BX+SI],EA=4524+BX+SI,
物理地址=DS:
EA
3.10用一条指令完成以下操作。
(1)把BX寄存器和DX寄存器的内容相加,结果存人DX寄存器中。
ADDDX,BX
(2)用寄存器BX和SI的基址变址寻址方式把存储器中的一个字节与AL寄存器的内容相加,并把结果送到AL寄存器中。
ADDAL,[BX+SI]
(3)用寄存器BX和位移量0B2H的寄存器相对寻址方式把存储器中的一个字和AX寄存器的内容互换。
XCHGAX,[BX+0B2]
(4)用位移量为0524H的直接寻址方式把存储器中的一个字与数2A59H相加,并把结果送回该存储单元中。
ADDWORDPTR[524],2A59H
3.11在数据段定义了ARRAY数组,其中依次存储了五个字数据,请用以下寻址方式的指令把第4个字送AX寄存器。
(1)直接寻址
MOVAX,ARRAY+6或MOVAX,[ARRAY+6]
(2)使用BX的间接寻址
LEABX,ARRAY+6;MOVAX,[BX]
(3)使用BX的寄存器相对寻址
LEABX,ARRAY;MOVAX,[BX+6]
(4)基址变址寻址
LEABX,ARRAY;MOVSI,6;MOVAX,[BX+SI]
3.12画出数据在数据段中的存放情况,程序执行后,BX、DI、CX、DX寄存器中的内容是什么?
程序如下:
datasegment
arraydw20,30,40,20h,30h,-6
buffdb‘abcd$’
dataends
codesegment
assumecs:
code,ds:
data
start:
movax,data
movds,ax
movbx,array+1
movdi,offsetarray
movcx,[di+5]
movdl,buff+3
movah,4ch
int21h
codeends
endstart
1E,00,00,00,20,00,00,64
3.13在DEBUG下设置(SP)=20H,设置AX、BX、CX、DX为不同值,把这四个寄存器内容依次压入堆栈,再从堆栈中依次弹出到SI、DI、BP、BX寄存器。
写出一段程序实现上述操作,并画出每条入栈指令执行后SP和堆栈中数据的变化。
3.14求出7450H与以下各十六进制数的和及差,并根据结果标出SF、ZF、CF、OF标志位的值。
(1)1234H
(2)5678H(3)9804H(4)E0A0H
SF、ZF、CF、OF
(1)1234H+7450H,1001
(2)5678H+7450H,1001
(3)9804H+7450H,0010
(4)E0A0H+7450H,0010
3.15在数据段有如下定义:
DATAXDW?
,?
DATAYDW?
,?
SUMDW?
,?
,?
,?
请用16位指令按下列要求写出指令序列:
(1)DATAX和DATAY两个字数据相加,和存放在SUM中。
MOVAX,DATAX
ADDAX,DATAY
MOVSUMAX
(2)DATAX和DATAY两个双字数据相加,和存放在SUM开始的字单元中。
MOVAX,DATAX
MOVDX,DATAX+2
ADDAX,DATAY
ADCDX,DATAY+2
MOVSUM,AX
MOVSUM+2,DX
(3)DATAX和DATAY两个字数据相乘(用MUL),积存放在SUM开始的字单元中。
(4)DATAX和DATAY两个双字数据相乘(用MUL),积存放在SUM开始的字单元中。
(5)DATAX双字除以字DATAY(用DIV),商和余数存放在SUM开始的字单元中。
(6)DATAX和DATAY两个压缩BCD码数据相加,和存放在SUM中。
3.16双字长数X存放在DX和AX中,设(DX)=1004H,(AX)=1002H,要求用16位指令写出:
(1)对存放在DX和AX中的双字长数求补的指令序列,并验证结果。
NOTAX
NOTDX
ADDAX,1
ADCDX,0
(2)用减法指令求0-X的指令序列,并验证结果。
MOVBX,0
MOVCX,0
SUBBX,AX
SBBCX,DX;结果在CX,BX
3.17试编写一个程序求出双字长数的绝对值。
双字长数在A开始的字单元中,结果存放在B开始的字单元中。
ADW?
,?
BDW?
,?
。
。
。
MOVAX,A
MOVDX,A+2
TESTDX,8000H
JZZS
NOTAX
NOTDX
ADDAX,1
ADCDX,0
ZS:
MOVB,AX
MOVB+2,DX
3.18用移位指令为主实现对AX中的无符号数乘以5,不考虑乘积可能超出16位。
MOVDX,AX
MOVCL,2
SHLAX,CL
ADDAX,DX
3.19用移位指令为主实现对AX中的无符号数乘以5,考虑乘积可能超出16位的情况。
提示:
用DX接AX左移的位,32位操作。
3.20把AX中的内容依次倒排序,即第0位移到第15位,第1位移到第14位,…。
3.21在数据段有如下定义:
BUFFDB‘ABCD$EFGHIJK$’
STR1DB12DUP(?
)
LENDB?
用串指令编写程序完成以下操作:
(1)对字符串STR1全部置空格符。
MOVAX,DATA
MOVDS,AX
MOVAL,20H
LEADI,STR1
MOVCX,STR1-BUFF
CLD
REPSTOSB
(2)从左到右把BUFF中的字符串传送到STR1。
MOVAX,DATA
MOVDS,AX
MOVES,AX
CLD
LEASI,BUFF
LEADI,STR1
MOVCX,STR1-BUFF
REPMOVSB
(3)从右到左把BUFF中的字符串传送到STR1。
MOVAX,DATA
MOVDS,AX
MOVES,AX
STD
LEASI,STR1-1
LEADI,LEN-1
MOVCX,STR1-BUFF
REPMOVSB
(4)比较BUFF与STR1两个字符串是否相等,如相等则DX=1,否则DX=0。
MOVAX,DATA
MOVDS,AX
MOVES,AX
CLD
LEASI,BUFF
LEADI,STR1
MOVCX,STR1-BUFF
REPECMPSB
(5)查找BUFF中有无字符$,把字符$出现的次数计入BX寄存器。
MOVAX,DATA
MOVES,AX
MOVBX,0
CLD
MOVAL,‘$’
LEASI,BUFF
MOVCX,STR1-BUFF
NEXT:
REPNESCASB
JCXZNO-FOUND
INCBX
JMPNEXT
3.22对于给定的AX和BX的值,执行下列程序段,程序将转向哪里?
ADDAX,BX
JNOL1
JNCL2
SUBAX,BX
JNCL3
JNOL4
JMPL5
(1)AX=1234H,BX=6789H
(2)AX=9200H,BX=4000H
(3)AX=420EH,BX=8031H
(4)AX=E002H,BX=8086H
L1,L1,L1,L5
3.23下面不完整的程序段是比较AX和BX的值,把其中大的数送MAX变量。
如果是无符号数,应如何填写指令?
如果是有符号数,应如何填写指令?
CMPAX,BX
(JBL1)有符号数:
JLL1
MOVMAX,AX
(JMPL2)
L1:
MOVMAX,BX
L2:
HLT
3.24在下列程序段的括号中分别填入如下指令,程序执行完后,AX、CX的内容是什么?
(1)LOOP
(2)LOOPE
(3)LOOPNZ
MOVAX,8
MOVCX,5
L1:
SHLAX,CL
()
提示:
上机,SHL指令使ZF=0,LOOPE指令不可能循环。
3.25测试AL寄存器,如果最高位和最低位同时为0,则转L0,如果最高位和最低位只有一位为1,则转L1,如果最高位和最低位同时为1,则转L2。
画出流程图,并编写程序段。
ROLAL,1
ANDAL,3
JZL0
SUBAL,3
JZL3
JMPL2
3.26从键盘输入一个英文字母,显示输出其大写。
画出流程图,并编写程序段。
3.27从键盘输入一位数字N,显示输出N个N。
画出流程图,并编写程序段。
CODESEGMENT
ASSUMECS:
CODE
START:
MOVAH,1
INT21H
MOVDL,AL
ANDAL,0FH
MOVCL,AL
MOVCH,0
NEXT:
MOVAH,2
INT21H
LOOPNEXT
MOV4CH
INT21H
CODEENDS
ENDSTART
3.28寄存器中为压缩的BCD码表示的十进制数,写出指令完成十进制加减计算,即计算AL+BL;AL-BL。
并在DEBUG下上机验证。
(1)AL=65H,BL=37H
(2)AL=98H,BL=69H
3.29寄存器中为非压缩的BCD码表示的十进制数,写出指令完成十进制加减计算,即计算AL+BL;AL-BL。
并在DEBUG下上机验证。
(1)AX=235H,BL=37H
(2)AL=238H,BL=39H
3.30用相对基址比例变址寻址方法求ARRAY行列式的值。
ARRAYDW2,3,5
DW1,4,6
DW2,7,9
习题4
4.1假设VAR1为字节变量,VAR2为字变量,LAB为标号,VAL为常量,指出下列有错误的指令,说出原因,并予纠正。
(1)ADDAX,VAR1/ADDAL,VAR1
(2)MOVVAR2,VAR1/MOVVAR2,AX
(3)MOVVAR1,BYTEPTRVAR2/MOVVAR1,AL
(4)MOVVAR1,OFFSETVAR2/MOVVAR2,OFFSETVAR1
(5)MOVVAR2,OFFSETVAR1
(6)MOVVAR1,VAR2+VAR1/MOVVAR2,VAR2-VAR1
(7)MOVVAR1,VAR2-VAR1/MOVVAR2,VAR2-VAR1
(8)MOVVAR2,VAR2-VAR1
(9)MOVBX,VAR2+VAL-4*5
(10)MOVBX,TYPEVAL
(11)MOVBX,LAB
(12)JMPVAR1/JMPWORDPTRVAR1
(13)JMPVAR2
(14)JMP[VAL]/仅在DEBUG下可以
(15)MOVBL,VAR1ANDVAL/VAR1ANDVAL须用指令实现
(16)MOVBX,VALAND0FH
(17)MOVBX,VALLT0FH
(18)MOVBL,LAB+VAR1/MOVBL,VAR1
4.2画图说明下列数据定义语句所示内存空间的数据,并回答寄存器的值。
ORG0
ARRAYLABELBYTE
DA1DW2,9,14,3,315H,-6
DA2DB7,‘ABCDEDFG’
LEN=$-DA2
ORG100H
DA3DWDA4
DA4DB4DUP(2DUP(1,2,3),4)
MOVAL,ARRAY+2(AL)=()H
ADDAL,DA2+1(AL)=()H
MOVAX,DA2-DA1(AX)=()H
MOVBL,LEN(BL)=()H
MOVAX,DA3(AX)=()H
MOVBX,TYPEDA4(BX)=()H
MOVBX,OFFSETDA4(BX)=()H
MOVCX,SIZEDA4(CX)=()H
MOVDX,LENGTHDA4(DX)=()H
MOVBX,WORDPTRDA4(BX)=()H
MOVBL,LENAND0FH(BL)=()H
MOVBL,LENGT5(BL)=()H
MOVAX,LENMOD5(AX)=()H
4.3变量和标号有哪些区别?
变量和标号有哪些属性?
如何获取属性值?
写出指令。
变量是为指令提供的操作数,标号是为指令提供标识,都是为了在指令中引用。
它们最主要的属性有:
偏移属性,段属性,类型属性。
例如:
MOVBX,OFFSETVAL;取偏移属性
MOVBX,SEGVAL;取段属性
MOVBX,TYPEVAL;取类型属性
4.4指令和伪指令的区别在哪里?
伪指令可以出现在代码段吗?
指令可以在数据段吗?
指令只能出现在代码段,定义数据的伪指令通常在数据段。
伪指令不会生成指令。
4.5下面的程序是否有错?
能否通过汇编?
程序运行的结果如何?
程序的真正意图是什么?
应如何修改程序才能实现真正意图?
答:
通过汇编和连接可以运行,但程序真正意图是输出ASCII码为30H~39H的字符0~9,应作修改。
CODESEGMENT
ASSUMECS:
CODE
K=30H;改为KDB30H
JDW0
START:
MOVDL,K
MOVAH,2
INT21H
K=K+1;K=K+1是伪指令,没生成代码,改为INCK
INCJ
CMPJ,10
JNZSTART
MOVAH,4CH
INT21H
CODEENDS
ENDSTART
4.6用32位指令编写完整程序,并上机调试,计算V=(X+Y)*R,其中所有变量均为64位变量,X、Y、R的具体数值由你自己确定,变量定义格式如下:
XDD?
?
YDD?
?
RDD?
?
VDD?
?
datasegment
xdd1
ydd2
rdd3
vdd?
?
dataends
codesegment
assumecs:
code,ds:
data
.386p
start:
movax,data
movds,ax
moveax,x
addeax,y
movebx,r
imulebx
movv,eax
movv+4,edx
movdl,al
adddl,30h
movah,2
int21h
movah,4ch
int21h
codeends
endstart
习题5
5.1下列程序是在3个数中找出最小的数并放入AL,在括号中填入指令使其完整。
moval,x
movbl,y
movcl,z
cmpal,bl
(jll1)
xchgal,bl
l1:
cmpal,cl
jlel2
(xchgal,cl)
l2:
ret
5.2数据段如下:
datasegment
da1db1,2,‘abcd’
count=$-da1
da2db9dup(?
)
dataends
补充括号处的指令,使得程序把DA1数据区数据移到DA2数据区。
movax,data
movds,ax
moves,(AX)
movcx,(COUNT)
movsi,(OFFSETDA1)
(MOVDI,OFFSETDA2)
(REPMOVSB)
5.3以下程序对无符号数组ARRAY的6个元素从小到大排序,补充括号处的指令。
datasegment
arraydw4,3,12,56,5,8
dataends
codesegment
assumecs:
code,ds:
data
start:
(movax,data)
(movds,data)
movcx,5
l1:
movdi,cx
movbx,0
l2:
movax,array[bx]
cmpax,array[bx+2]
(jll3)
xchgax,array[bx+2]
movarray[bx],ax
l3:
addbx,2
(loopl2)
movcx,di
loopl1
movah,4ch
int21h
codesegment
endstart
5.4编写程序,实现从键盘输入的小写字母用大写字母显示出来。
对输入须合法性检查。
codesegment
assumecs:
code
start:
pushds
subax,ax
pushax
movah,1
int21h
cmpal,61h
jbexit
cmpal,7ah
jaexit
subal,20h
movdl,al
movah,2
int21h
exit:
ret
codeends
endstart
5.5编写程序,比较两个字符串是否相同,如果相同,则显示两个字符串,如果不同,则显示发现不同的字符位置。
datasgsegment
mess1db13,10,'inputstring1:
$'
mess2db13,10,'inputstring2:
$'
mess3db13,10,'match!
$'
mess4db13,10,'nomatchat$'
st1labelbyte
max1db6
act1db?
stok1db6dup(?
)
st2labelbyte
max2db6
act2db?
stok2db6dup(?
)
datasgends
cod