文档库 最新最全的文档下载
当前位置:文档库 › 北航考研机械972 微机原理作业答案_3-5章

北航考研机械972 微机原理作业答案_3-5章

8086第三章作业

3-11在实模式下,若段寄存器中装入如下数值,试写出每个段的起始地址和结束地址

(1)1000H 10000H-1FFFFH

(2)1234H 12340H-2233FH

(3)E000H E0000H-EFFFFH

(4)AB00H AB000H-BAFFFH

3-12对于下列CS:IP组合,计算出要执行的下条指令存储器地址。

(1)CS=1000H和IP=2000H 答:下条指令存储器地址:12000H

(2)CS=2400H和IP=1A00H 答:下条指令存储器地址:25A00H

(3)CS=1A00H和IP=B000H 答:下条指令存储器地址:25000H

(4)CS=3456H和IP=ABCDH 答:下条指令存储器地址:3F12DH

3-37 指出下列指令源操作数的寻址方式

(1)MOV AX,1200H;立即数寻址

(2)MOV BX,[1200H];直接寻址

(3)MOV BX,[SI];变址寻址

(4)MOV BX,[BX+SI+1200];相对基变址寻址

(5)MOV [BX+SI],AL;寄存器寻址

(6)ADD AX,[BX+DI+20H];相对基变址寻址

(7)MUL BL ;寄存器寻址

(8)JMP BX ;间接寻址

(9)IN AL,DX ;寄存器间接寻址

(10)INC WORD PTR[BP+50H] ;相对基址寻址

小结:虽然对存储器的访问指令、输入/输出指令(IN指令和OUT指令)、跳转指令(JMP指令)都有直接寻址和间接寻址,但是形式是有很大差别的:1.直接寻址:

(1)对于存储器的访问用方括号括起来的二进制数,

如:MOV BX,[1200H]

(2)对于输入/输出指令(IN指令和OUT指令)用二进制数

如:IN AX,8FH 又如: OUT 78H,AL

(3)对于跳转指令(JMP指令)是以目标标号为直接地址的

如: JMP ADDR1

2.间接寻址:

(1)对于存储器的访问有分为基址寻址、变址寻址、基址加变址寻址以及带位移量的所谓相对基址寻址、相对变址寻址、相对基址加变址寻址如:MOV AX,[BP]

(2)对于输入/输出指令用DX做间接寻址寄存器

如:IN AX,DX 又如: OUT DX,AL

(3)跳转指令直接写明寄存器即可 (段内)

如: JMP BX

段间需组合:如: JMP DWORD PTR [BX+ADDR1]

3-38指出8086/8088下列指令中存储器操作数地址的计数表达式。

(1)M OV AL,[DI] 答:存储器操作数地址的计数表达式为:(DS)×16+(DI)(2)M OV AX,[BX+SI] 答:地址的计数表达式为:(DS)×16+(BX)+(SI)(3)M OV 8[BX+SI],AL 答:地址的计数表达式为:(DS)×16+8+[(BX)+(SI)] (4)A DD AL,ES:[BX] 答:地址的计数表达式为:(ES)×16+(BX)

(5)S UB AX,[1000H] 答:地址的计数表达式为:(DS)×16+1000H

(6)A DC AX,[BX+DI+2000H] 答:地址表达式为:(DS)×16+(BX)+(DI)+2000H

(7)M OV CX,[BP+SI] 答:地址的计数表达式为:(SS)×16+(BP)+(SI)(8)I NC BYTE PTR(DI)答:地址表达式为:(DS)×16+(DI)

注:段寄存器的分工:

1.代码段(程序段):CS

2.数据段:①一般DS;②当用BP(及其组合)间接寻址偏移量时,用SS段寄存器;③串操作时,源段(与SI组合)用DS;目标段(与DI组合)

用ES

3.堆栈段:①与堆栈相关的指令;②当用BP(及其组合)间接寻址偏移量时,用SS段寄存器;

4.附加段:①加段超越运算符(如38-(4);;②串操作时,目标段(与DI组合)用ES

3-39 指出8086/8088下列指令的错误何在?

1.MOV [SI],IP 答:IP不可访问:

2.MOV CS,AX 答:CS不可访问:

3.MOV BL,SI+2答:类型不匹配,或者变址寻址寄存器未加方括号。应写成MOV BL,[SI+2]或MOV BX,SI+2

4.MOV 60H,BL 答:立即数不能做目标操作数。

5.PUSH 2400H 答:PUSH的源操作数不能是立即数。

6.INC [BX] 答:对于间接寻址的存储单元加1指令,数据的长度必须用BYTE PTR、WORD PTR或DWORD PTR类型伪指令加以说明,否则,汇编程序不能确定是对字节、字还是双字加1。(P92)

7.MUL –60H 答:无符号乘法指令,操作数不能用立即数。

8.ADD [2400H],2AH 答:[2400h]前要加类型说明

9.MOV [BX],[DI] 答:在MOV指令中,两个操作数不能都是存储器操作数。

10.MOV SI,AL 答:两个操作数的长度不一样,类型不匹配。

有的同学所答非所问,问错在哪里,却作成了改成正确的。

3.40 MOV CS,AX指令会带来什么错误?

答:这样做会影响后面指令,因为CS的改变不能按要求执行。提示遇到了无效指令。

3-41 阅读下列程序段,指出每条指令执行以后有关寄存器的内容是多少?

MOV AX,0ABCH ;AX寄存器的内容是:0ABCH

DEC AX ;AX寄存器的内容是:0ABBH

AND AX,00FFH ;AX寄存器的内容是:00BBH

MOV CL,4 ;CL寄存器的内容是:04H

SAL AL,1 ;AL寄存器的内容是:76H

MOV CL,AL ;CL寄存器的内容是:76H

ADD CL,78H ;CL寄存器的内容是:0EEH

PUSH AX ;(SS*16+SP)=0076H,AX寄存器的内容是:0076H POP BX ;BX寄存器的内容是:0076H

3.42 指出RET与IRET两条指令的区别,并说明各用在什么场合?

答:(1)RET与IRET是两条返回主程序的返回指令,但RET是与过程(子程序)调用指令CALL对应使用的过程返回指令,而IRET是与中断指令INT n对应使用的中断返回指令。

(2)RET指令应安排在过程的出口即过程的最后一条指令处,它的功能是从堆栈顶部弹出由CALL指令压入的断点地址值,迫使CPU返回到调用程序的断点去继续执行。

IRET指令总是安排在中断服务程序的出口处,由它控制从堆栈中弹出程序断点送回CS和IP中,弹出标志寄存器内容送回F中,迫使CPU返回到断点去继续执行后续程序。

3.43 说明MOV BX,DATA和MOV BX,OFFSET DATA指令之间的区别?

答:MOV BX,DATA直接将DATA的值赋给BX,MOV BX,OFFSET DATA是将DATA在段内的偏移地址赋给BX.

3.44 给定DS=1100H,BX=0200H,LIST=0250H,SI=0500H。试指出下面各条指令寻址存储器的地址。

(1)M OV LIST[SI],EDX ; PA=DS*16+LIST+SI=11750H

(2)M OV CL,LIST[BX+SI];PA=DS*16+LIST+BX+SI=11950H

(3)M OV CH,[BX+SI];PA=DS*16+BX+SI=11700H

(4)M OV DL,[BX+100H];PA=DS*16+BX+100H=11300H

3.45 假定PC机存储器地地址区有关单元的内容如下:

(20H)=3CH,(21H)=00H,(22H)=86H,(23H)=0EH,且CS=2000H,IP=0010H,SS=1000H,SP=0100H,FLAGS=0240H,这时若执行INT 8指令,试问:

(1)程序转向从何处执行(用物理地址回答)?

(2)栈顶6个存储单元的地址(用逻辑地址回答)及内容分别是什么?

答:(1)程序转向0E89CH处执行,中断服务程序的入口地址在00020H-00023H 单元。

(2)栈顶6个单元的内容1000H:00FEH 0240H

1000H:00FCH 2000H

1000H:00FAH 0012H

注:执行INT 8指令(2个字节)使F寄存器内容先入栈,断点再入栈保护,同时中断服务程序的入口地址赋值给CS和IP

3-46 设SP=2000H,AX=3000H,BX=5000H,执行下列片段程序后,SP=?AX=?BX=?

PUSH AX

PUSH BX

POP AX

答:执行以上片段程序后,SP=1FFEH;AX=5000H;BX=5000H

注:8086/8088的堆栈方向与51单片机相反:执行PUSH 堆栈指针被修改:SP-2 SP

执行POP 堆栈指针被修改:SP+2 SP

3-48 设AX=5555H,BX=FF00H,执行下列片段程序后,AX=?BX=?CF=?

AND AX,BX ;AX=5500H

XOR AX,AX ;AX=0000H

NOT BX ;BX=00FFH

答:执行以上片段程序后,AX=0000H;BX=00FFH;CF=0

注:“与”“或”“异或”指令使CF清零,“非”指令不影响CF

3-50 若DS=3000H,BX=2000H,SI=0100H,ES=4000H,计算出下述各条指令中存储器操作数的物理地址。

1. MOV [BX],AH 答:存储器操作数物理地址为:(DS)×16+(BX)=32000H

2.ADD AL,[BX+SI+1000H] 答:物理地址为:(DS)×16+(BX+SI+1000H)=33100H

3.MOV AL,[BX+SI] 答:物理地址为:(DS)×16+(BX)+(SI)=32100H 4.SUB AL,ES:[BX] 答:物理地址为:(ES)×16+(BX)=42000H

3-52 选用最少指令,实现下述要求的功能。

1.AH的高4位清零。AND AH,0FH

2.AL的高4位取反。XOR AL,0F0H

3.AL的高4位移到低4位,高4位清零。

(一)MOV CL,4

SHR AL,CL ;逻辑移位,补0

(二)MOV CL,4

ROR AL,CL

AND AH,0FH

4.AH的低4位移到高4位,低4位清零。

(一)MOV CL,4

SHL AH,CL ;逻辑移位,补0

(二)MOV CL,4

ROL AH,CL

AND AL,0F0H

3.53设BX=6D16H,AX=1100H,执行指令后的结果

MOV CL,06H ;CL=6

ROL AX,CL ;AX=4004H

SHR BX,CL ;BX=01B4H

3-54 设初值AX=0119H,,执行下列程序段后,AX=?

MOV CH,AH ;(CH)=01H

ADD AL,AH ;(AL)=1AH ,CF=0

DAA ;(AL)=20H ,CF=0

XCHG AL,CH;;(CH)=20H ,AL=01H ,不影响标志位状态ADC AL,34H ;(AL)=35H

DAA ;(AL)=35H

MOV AH,AL ;(AH)=35H

MOV AL,CH ;(AL)=20H

HLT

(AX)=3520H

只写最后结果也行,但如果写错了,中间的过程起作用。

3.55 AX=6264H,CX=0004H,执行指令段后=?

AND AX,AX;(AX)=6264H

JZ DONE ;ZF=0,顺序执行

SHL CX,1;(CX)=0008H

ROR AX,CL;(AX)=6462H

DONE:OR AX,1234H;(AX)=7676H

3-56 写出可使AX清零的几条指令。

1.MOV AX,0000H

2.AND AX,0000H

3.XOR AX,AX

4.SUB AX,AX

3.59 哪个段寄存器不能从堆栈弹出?

答:CS段寄存器的内容可以压入堆栈,却不能从堆栈弹出。P84

3-62 若AX=1001H,DX=20FFH,当执行ADD AX,DX指令以后,请列出和数及标志寄存器中每个位的内容。

0001000000000001

+ 0010000011111111

0011000100000000-----3100H CF=0;AF=1;SF=0;ZF=0;OF=0 PF=0(只与运算结果的低8位有关)

3.76 设计一个程序段,将AX和BX中的8位BCD数加CX和DX中的8位BCD数(AX 和CX是最高有效寄存器),加法以后的结果存入CX和DX中。

PUSH AX

PUSH CX

MOV AX,DX

ADD AL,BL;低字节相加

DAA ;低字节调整

MOV CL,AL

MOV AL,AH

ADC AL,BH; 高字节相加

DAA ;高字节调整

MOV DH,AL

MOV DL,CL;(BX)+(DX)和放到DX中

POP CX

POP AX

ADC AL,CL;低字节相加

DAA ;低字节调整

MOV CL,AL

MOV AL,AH

ADC AL,CH; 高字节相加

DAA ;高字节调整

MOV CH,AL;(AX)+(CX)和放到CX中

3-81 设计一个程序段,将AX中的最右4位置1,将AX中的最左3位清0,并且把AX中的7、8、9位取反。

OR AX,000FH

AND AX,1FFFH

XOR AX,0380H; 01C0H 0000 0011 1000 0000

0000 0001 1100 0000

3.82 选择正确的指令以实现下列任务

(1)DI右移3位,再把0移入最高位

(2)AL中的所有位左移1位,使0移入最低位

(3)AL循环左移3位

(4)DS带进位位循环右移1位

答:(1)MOV CL,3

SHR DI,CL

(2)SAL AL,1

(3)MOV CL,3

ROL AL,CL

(4)RCR DX,1

3-86 用串操作指令设计实现如下功能的程序段:先将100个数从6180H处搬移到2000H处;再从中检索出等于AL中字符的单元,并将此单元置换成空格符。

CLD

MOV CX,100

MOV SI,6180H

MOV DI,2000H

REP MOVSB ;至此完成了将100个数从6180H处搬移到2000H处

MOV CX,100

MOV DI,2000H

MOV AL,DATA

CH1:JCXZ STO

REPNE SCASB

JZ CH2

JMP CH1

CH2:MOV AH,20H

DEC DI

MOV [DI],AH ;MOV BYTE PTR[DI],20H

INC DI

JMP CH1

STO:HLT

方法2

MOV SI,6180H

MOV DI,2000H

MOV CX,100

CLD

LP1:LODSB

STOSB

LOOP LP1

MOV AL,DATA

MOV CX,100

MOV DI,2000H

CH1:JCXZ STO

REPNE SCASB

JZ CH2

JMP CH1

CH2:MOV AH,20H

DEC DI

MOV [DI],AH ; MOV BYTE PTR[DI],20H

INC DI

JMP CH1

STO:HLT

3.88 带参数的返回指令用在什么场合?设栈顶地址为2000H,当执行RET 0008后,问SP的值是多少?

答:(1)带参数的返回指令RET用在调用程序需要通过堆栈向过程传送一些参数的场合,并在过程运行中要使用这些参数,一旦过程执行完毕,这些参数应弹出堆栈作废。RET指令放在被调用的过程末尾处。

(2)SP=2+8或SP=4+8取决于子程序是近过程还是远过程,先从堆栈弹出断点,再从堆栈弹出8个字节并丢弃之。即SP=200AH或SP=200CH

3.89 在执行IRET 和RET时,具体操作内容有什么区别?

答:执行中断返回指令IRET 时,具体操作内容为:

(1)先将由SP 所制定的堆栈内容弹出至IP ,恢复IP 值: IP (SP),SP (SP)+2

(2)再将由SP 所制定的堆栈内容弹出至CS ,恢复CS 值: CS (SP),SP (SP)+2

(3)最后将SP 制定的堆栈内容弹出至FLAGS: FLAGS (SP),SP (SP)+2

执行过程返回指令RET 时,具体操作内容为:同上(1)(2)步内容,无(3)步操作

3.90 INT 40H 指令的中断向量存储在哪些地址单元?是用图解说明中断向量的含义和具体内容,并指出它和中断入口地址之间是什么关系?

答:因为40H*4=0100H ,可知其中断向量存储在0100H-0103H 。

第四章 汇编语言程序设计

4-2 下列程序执行后,寄存器AX ,BX ,CX 的内容分别是多少? D SEGMENT AT 0202H;定位数据段地址 ORG 0202H ;定位偏移地址 DA_WORD DW 20H

MOV AX,DA_WORD ;(AX)=0020H MOV BX,OFFSET DA_WORD ;(BX)=0202H

MOV CL,BYTE PTR DA_WORD ;(CL)=20H (将变量DA_WORD 的属性改变为字节型)

MOV CH,TYPE DA_WORD ;(CH)=2(变量类型数值) ;(CX )=0220H

4-4 试编制一程序,把CHAR1中各小写字母分别转换为对应的大写字母,并存放在CHAR2开始的单元中(题目要求:不改变CHAR1的内容)

方法1,小写字母转换一个输出显示一个,前3种方法均使用了AL 寄存器

D SEGMENT CHAR1 DB "abcdefghijklmnopqrstuvwxyz"

N EQU $-CHAR1;变量必须先定义后使用,而不能相反

0000H:0100H

0000H:0100H 0000H:0100H 0000H:0100H

IPL

IPH CSL CSH

CHAR2 DB N DUP(0) ; ;不能把此句与上一句对调,CHAR2 DB $-CHAR1

有;的同学这样写,错在哪

D ENDS

S SEGMENT STACK

DB 200 DUP(0)

S ENDS

C SEGMENT

ASSUME CS:C,DS:D,SS:S ;ASSUME是伪指令,后面不能写冒号

START: MOV AX,D

MOV DS,AX

;MOV ES,AX ;只要用到串操作指令且DI

LEA SI,CHAR1 ;MOV SI,OFFSET CHAR1

LEA DI,CHAR2 ; MOV DI,OFFSET CHAR2

MOV CX,N ;$-CHAR1,不可以

AGAIN:MOV AL,[SI]

SUB AL,20H ;AND AL,5FH有的同学是这样实现

MOV [DI],AL

MOV DL,AL

MOV AH,2

INT 21H ;从屏幕显示

INC SI

INC DI

LOOP AGAIN

MOV AH,4CH

INT 21H ; ;不是必须的

C ENDS

END START

方法2:使用通用数据传送指令MOV

D SEGMENT

CHAR1 DB ‘abcdefghijklmnopqrstuvwxyz’

N EQU $-CHAR1;变量必须先定义后使用,而不能相反

CHAR2 DB N DUP(0);不能把此句与上一句对调

D ENDS

STACK SEGMENT STACK

DB 200 DUP(0)

STACK ENDS ;P126(代码段和堆栈段是不可少的)

C SEGMENT

ASSUME CS:C ,DS:D ,SS:S

START: MOV AX,D

MOV DS,AX

MOV ES,AX ;只要用到串操作指令且DI

MOV SI,0 ;

MOV DI,0 ;

MOV CX,N

AGAIN: MOV AL,CHAR1[SI] ;

SUB AL,20H MOV CHAR2[DI],AL ;

INC SI

INC DI

LOOP AGAIN

MOV AH,4CH

INT 21H ;不是必须的

C ENDS

END START

第3种方法:使用串的读写指令LODSB STOSB

D SEGMENT

CHAR1 DB ‘abcdef’

N EQU $-CHAR1

CHAR2 DB $-CHAR1 DUP(0) D ENDS

STACK SEGMENT STACK

DB 200 DUP(0)

STACK ENDS ;P126(代码段和堆栈段是不可少的)

C SEGMENT

ASSUME CS:C,DS:D,SS:S

START: MOV AX,D

MOV DS,AX

MOV ES,AX

MOV SI,OFFSET CHAR1 ;LEA SI,CHAR1

MOV DI, OFFSET CHAR2 ;LEA DI,CHAR2

MOV CX,N

CLD ;不写(隐含)也是0(递增)但不能STD

AGAIN: LODSB ;执行一次,隐含修改SI

SUB AL,32 STOSB ;MOV [DI],AL;执行一次, 隐含修改DI INC DI LOOP AGAIN ;LOOP指令只修改CX,不管SI,DI

MOV AH,4CH

INT 21H ;不是必须的

C ENDS

END START

第四种方法2006级,没有显示使用MOVSB指令

D SEGMENT

CHAR1 DB "abcdefghijklmnopqrstuvwxyz"

N EQU $-CHAR1

CHAR2 DB N DUP(0)

D ENDS

S SEGMENT STACK

DB 200 DUP(0)

S ENDS

C SEGMENT

ASSUME CS:C,DS:D,SS:S

START:

MOV AX,D

MOV DS,AX

MOV ES,AX

LEA SI,CHAR1

LEA DI,CHAR2

MOV CX,N

AGAIN:MOVSB ; SUB [SI],20H

DEC DI ; MOVSB

SUB BYTE PTR[DI],20H ;LOOP AGAIN 错在哪里?结果如

何?

INC DI

LOOP AGAIN

MOV AH,4CH

INT 21H

C ENDS

END START

方法5: 只用一个地址指针SI

D SEGMENT

CHAR1 DB "abcdefghijklmnopqrstuvwxyz"

N EQU $-CHAR1

CHAR2 DB N DUP(0)

D ENDS

S SEGMENT STACK

DB 200 DUP(0)

S ENDS

C SEGMENT

ASSUME CS:C,DS:D,SS:S

START:

MOV AX,D

MOV DS,AX

MOV ES,AX

MOV SI,0

MOV CX,N

AGAIN:MOV AL,CHAR1[SI] ;只用一个地址指针,SI[CHAR1]是错误的

SUB AL,20H

MOV CHAR2[SI],AL

INC SI

LOOP AGAIN

int 3

MOV AH,4CH

INT 21H

C ENDS

END START

有的同学按数据是由键盘录入的来考虑的,也可行,程序中还有不少问题

方法6:由键盘输入小写字母再转换输出,回车符也占一个字节,输入需要小写转换成大写字母的内容从输入串的第3个元素开始

D SEGMENT

A DB"CHAR1",0DH,0AH,"$"

B DB"CHAR2",0DH,0AH,"$"

CHAR1 DB 11,?,11 DUP(0);准备输入10个小写字母

CHAR2 DB 10 DUP(0)

D ENDS

S SEGMENT STACK

DB 200 DUP(0)

S ENDS

C SEGMENT

ASSUME CS:C,DS:D,SS:S

START:

MOV AX,D

MOV DS,AX

MOV ES,AX

MOV DX,OFFSET A

MOV AH,9

INT 21H

LEA DX,CHAR1

MOV AH,0AH

INT 21H ;由键盘输入字符串,10个字母(显示),1个回车,共11个字节

LEA SI,CHAR1[2]

LEA DI,CHAR2

MOV CX,10 ;需要转换的字符长度为10个字节

AGAIN:MOV AL,[SI]

SUB AL,20H

MOV [DI],AL

INC SI

INC DI

LOOP AGAIN ; 将小写字母字符串转换成大写字母字符串

MOV BYTE PTR[DI],0DH

INC DI

MOV BYTE PTR[DI],0AH

INC DI

MOV BYTE PTR[DI],'$' ;必须指明数据类型

MOV DX,OFFSET CHAR2

MOV AH,9

INT 21H ;输出'$'结尾的大写字母字符串

int 3

MOV AH,4CH

INT 21H

C ENDS

END START

4-6在BUF地址处起,存放有100个字节的字符串,设其中有一个以上的“A”字符,编程查找出第一个“A”字符相对起始地址的距离,并将其存入LEN单元。

方法1,经过调试,数据串长N

D SEGMENT

BUF DB 'qasdA%^9F26HsdfhA$#12345678'

DB 'DFGH234546JII2334JI5467OPPAVG'

DB 'ASDFG45667RTY' ; 必须写实际的

N EQU $-BUF

LEN DW 0;为变量LEN保留一个字,必须先定义后使用,LEN DW ?

D ENDS

S SEGMENT STACK

DB 200 DUP(0)

S ENDS

C SEGMENT

ASSUME CS:C,DS:D,SS:S

START: MOV AX,D

MOV DS,AX

MOV ES,AX ;这条指令是必须的 MOV CX,N

LEA DI,BUF ;MOV DI ,OFFSET BUF MOV AL,41H ;MOV AL,‘A ’

REPNE SCASB ;有的同学用的比较指令 MOV LEN,[DI-1]错在哪里 ,

MOV LEN,OFFSET BUF[DI-1]对不对 或LEA LEN,BUF[DI-1] MOV AH,4CH INT 21H

C ENDS

END START

4-8 某程序设置的数据区如下所示,画出该数据段内容在内存中的存放形式(要用十六进制补码表示,按字节组织) DATA SEGMENT DB1 DB 12H,34H,0,56H DW1 DW 78H,90H,0AB46H,1234H

ADR1 DW DB1 ;取变量DB1的偏移地址

ADR2 DW DW1 ;;取变量DW1的偏移地址

AAA DW $-DB1 ;计算当前变量到DB1变量的字节数

BUF DB 5 DUP(0) DATA ENDS 有的同学认为0AB46H 是负数,并取了它的补码

4-10 以BUF1和BUF2开头的2个字符串,其长度均为LEN ,试编程实现: (1)将BUF1开头的字符串送到BUF2开始的内存空间。 (2)将BUF1开始的内存空间全部清零。

经过调试的:方法1:数据段与附加段重叠,利用MOVSB 指令实现数据传的复制

0000H DB1 0004H DW1 000CH ADR1

000EH ADR2 0010H AAA 0012H BUF

D SEGMENT

D1 DB 'BUF1QWE233459JKGHGFHGF';看清题目要求,写出实际内容对存

储器初始化,分配内存空间,不能偷懒LEN DB $-D1

D2 DB ' BUF2ASD33459JKGHGFHGFI';长度与D1相同

D ENDS

S SEGMENT STACK

DB 200 DUP(0)

S ENDS

C SEGMENT

ASSUME CS:C,DS:D,SS:S

STAR:

MOV AX,D

MOV DS,AX

MOV ES,AX ;附加段与数据段重叠,是允许的

LEA SI,D1

LEA DI,D2

MOV CX,LEN

REP MOVSB

LEA DI,D1

MOV CX,LEN ;这条语句不能少

MOV AL,00H ;MOV AX,0错在哪

REP STOSB

MOV AH,4CH

INT 21H

C ENDS

END STAR

经过调试的:方法2;数据段与附加段分开,串读一个写一个实现数据的传送,再利用串写指令使指定存储区清零

D SEGMENT

D1 DB 'BUF1qasdA%^9F26HsdfhA$#12345678'

LEN EQU $-D1

D ENDS

E SEGMENT

D2 DB "BUF2abcdefghijklmnopqrstuvwxyz0" ; 必须写实际的,

;与D1长度相同

E ENDS

S SEGMENT STACK

DB 200 DUP(0)

S ENDS

C SEGMENT

ASSUME CS:C,DS:D,SS:S

START: MOV AX,D

MOV DS,AX

MOV AX,E

MOV ES,AX

MOV CX,N

LEA SI,D1 ;MOV SI,OFFSET D1

LEA DI,D2

LP: LODSB

STOSB

LOOP LP ;LOOP只是使CX减1,不改变SI DI

LEA DI,D1

MOV CX,N ;这条语句不能少

MOV AL,00H

REP STOSB

MOV AH,4CH

INT 21H

C ENDS

END START

第3种做法:传送一个字节清零一个字节,再向下一个字节进行

D SEGMENT

D1 DB 'BUF1QWE233459JKGHGFHGF';看清题目要求,写出实际内容对存

储器初始化,分配内存空间,不能偷懒LEN DB $-D1

D2 DB ' BUF2ASD33459JKGHGFHGFI';长度与D1相同

D ENDS

S SEGMENT STACK

DB 200 DUP(0)

S ENDS

C SEGMENT

ASSUME CS:C,DS:D,SS:S

STAR: MOV AX,D

MOV DS,AX

MOV ES,AX

LEA SI,D1

LEA DI,D2

MOV CX,LEN

NEXT:MOV AL,[SI]

MOV [DI],AL

MOV [SI],00H

INC SI

INC DI

LOOP NEXT

MOV AH,4CH

INT 21H

CSEG ENDS

END STAR

方法4;4-10-4从键盘输入初值,并显示

D SEGMENT

BUF1 DB 101,?,101 DUP(0)

BUF2 DB 100 DUP(0)

BUF3 DB 100 DUP(0)

A D

B 'BUF1',0DH,0AH,'$'

B DB 'BUF2',0DH,0AH,'$'

D ENDS

S SEGMENT STACK

DB 200 DUP(0)

S ENDS

C SEGMENT

ASSUME CS:C,DS:D,SS:S

START: MOV AX,D

MOV DS,AX

MOV ES,AX

MOV DX,OFFSET A

MOV AH,9

INT 21H ;输出显示'BUF1'

MOV DX,OFFSET BUF1

MOV AH,0AH

INT 21H ;键盘输入字符串

MOV CL,[BUF1+1] ;实际输入的字符串长度送CL,取相应单元的内容需加方括号

MOV CH,0

PUSH CX

CLD

LEA SI,BUF1+2

LEA DI,BUF2

REP MOVSB ;将输入的字符串传送到BUF2

MOV BYTE PTR[DI],0DH

INC DI

MOV BYTE PTR[DI],0AH

INC DI

MOV BYTE PTR[DI],'$';在BUF2末尾输入回车换行和‘$'

MOV SI,OFFSET BUF3

MOV DI,OFFSET BUF1+2;取变量的偏移地址,不能加方括号

POP CX

REP MOVSB ;用BUF3替换BUF1

MOV BYTE PTR[DI],0DH

INC DI

MOV BYTE PTR[DI],0AH

INC DI

MOV BYTE PTR[DI],'$';在BUF1末尾输入回车换行和‘$'

MOV DX,OFFSET A

MOV AH,9

INT 21H ;输出显示’BUF1'

MOV DX,OFFSET BUF1+2

MOV AH,9

INT 21H ;输出空格,因为BUF1已经清零了

MOV DX,OFFSET B

MOV AH,9

INT 21H ;输出显示’BUF2'

MOV DX,OFFSET BUF2

MOV AH,9

INT 21H ;输出BUF2,即键盘输入的内容

MOV AH,4CH

INT 21H

C ENDS

END START

4-14`试编写一程序,找出BUF数据区中带符号数的最大数和最小数,把最大

数放到BH单元,把最小数放到BL单元。

D SEGMENT

BUF DB 5,90,-45,100,99,………,-12

N EQU $-BUF

D ENDS

STACK SEGMENT STACK

DB 200 DUP(0)

STACK ENDS

C SEGMENT

ASSUME CS:C,DS:D,SS:S

START: MOV AX,D

MOV DS,AX

MOV CX,N-1

MOV SI,0

MOV BH,BUF[SI]

MOV BL,BUF[SI]

AGAIN: INC SI

CMP BH,BUF[SI]

JGE NEXT ;JAE NEXT错(无符号数)

MOV BH,BUF[SI]

ABC: LOOP AGAIN ;这句不要也行

NEXT: CMP BL,BUF[SI]

JLE ABC

MOV BL,BUF[SI]

LOOP AGAIN

C ENDS

END START

4-16 若AL中的内容为2位压缩的BCD数68H,试编程:(1)将其拆开成非压

缩的BCD数,高低位分别存入BH和BL中。

(2)将上述要求的2位BCD码变换成对应的ASCII码,并且存入CH和CL中。

方法1,经过调试的

S SEGMENT STACK

DB 10 DUP(?)

S ENDS

C SEGMENT

ASSUME CS:C,SS:S,DS:D

STAR:MOV AX,D

MOV DS,AX

MOV AL,68H

MOV BH,AL

AND AL,0FH

MOV BL,AL ;(BL)是低位非压缩的BCD码

AND BH,0F0H ;(BH)将是高位非压缩的BCD码

MOV CL,4

SHR BH,CL ;(BH)是高位非压缩的BCD码

MOV CL,BL

ADD CL,30H ;(CL)是低位ASCII码

MOV CH,BH

ADD CH,30H ;(CH)是高位ASCII码

MOV AH,4CH

INT 21H

C ENDS

END STAR

方法2

D SEGMENT

D1 DB 1,2,3

D ENDS

S SEGMENT STACK

DB 10 DUP(?)

S ENDS

C SEGMENT

ASSUME CS:C,SS:S,DS:D

STAR:MOV AX,D

MOV DS,AX

MOV SI,OFFSET D1

MOV DL,68H

MOV AL,68H

AND AL,0FH

MUL BYTE PTR[SI]

AAM ;乘法的ASCII码调整指令,P99

MOV BL,AL

MOV BH,DL

AND BH,0F0H

MOV CL,4

SHR BH,CL

MOV AL,BH

MUL BYTE PTR[SI]

AAM

MOV BH,AL

MOV CL,BL

ADD CL,30H

MOV CH,BH

ADD CH,30H

C ENDS

END STAR

4-18试用子程序结构编写一程序:从键盘输入一个2位十进制的月份数(01~12),然后显示出相应的英文缩写名。

提示:根据题目要求实现的功能,可编写用一个主程序MAIN分别调用几个子程序。

(1)I NPUT从键盘接收一个2位数,并把它转换为对应的二进制数。

(2)L OCATE 把输入的月份数与其英文缩写名(如JAN,FEB,MAR,APP,MAY,JUN等)对应起来,制成一个字符表以便查找。

(3)D ISPLAY 将找到的缩写字母在屏幕上显示出来,显示可用DOS所提供的显示功能(INT 21H的09号功能)。

方法1:与方法2的不同主要在数据表的制定

D SEGMENT

D1 DB "Please input month from the keyboad",0DH,0AH,"$"

D2 DB 4, ?,4 DUP(?);分配键盘输入缓冲区,回车符占一个字节,

但实际输入的字符数中不包含它,即输入2位数至少需预留3个字节的

空间,输入完成后,实际输入的字符数为2

D3 DB "ERROR",0DH,0AH,"$"

MONTH0 DB "JAN",0DH,0AH,"$"

DB "FEB" ,0DH,0AH,"$"

DB "MAR" ,0DH,0AH,"$"

DB "APP" ,0DH,0AH,"$"

DB "MAY" ,0DH,0AH,"$"

DB "JUN" ,0DH,0AH,"$"

DB "JUL" ,0DH,0AH,"$"

DB "AUG" ,0DH,0AH,"$"

DB "SEP" ,0DH,0AH,"$"

DB "OCT" ,0DH,0AH,"$"

DB "NOV" ,0DH,0AH,"$"

DB "DEC" ,0DH,0AH,"$"

D ENDS

S SEGMENT STACK

DB 200 DUP(0)

S ENDS

C SEGMENT

ASSUME CS:C,DS:D,SS:S

START:CLD

MOV AX,D

MOV DS,AX

CALL INPUT

CALL LOCATE

CALL DISPLAY

MOV AH,4CH

INT 21H

INPUT PROC NEAR

LEA DX, D1 ;将D1表示的相对地址送DX

MOV AH,9

INT 21H ;显示‘Please input month from the keyboad’并换行

ww2:LEA DX,D2 ;输入月份

MOV AH,0AH

INT 21H

LEA DI,D2 ;将D2表示的相对地址送DI

CMP byte ptr [DI+1],2

JNE ww2 ;输入的如果不是二位数,是错误

MOV AH,[DI+2];输入的月份高字节(十位数)

MOV AL,[DI+3];输入的月份低字节(个位数)

XOR AX,3030H ;将ASCII码变成BCD码

MOV BX,AX

MOV AL,BH

mov dl,0ah

MUL dl ;变成二进制数

MOV BH,AL

MOV AL,BL ;输入的月份低字节(个位数)

ADD AL,BH ;AL=1-12

RET ;是必须的

INPUT ENDP ;是必须的

LOCATE PROC NEAR

DEC AL

CMP AL,0CH

JNC ERROR ;≥12(正确的情况应该是0-11),输入错误

MOV BL,06H

MUL BL

LEA SI,MONTH0

ADD SI,AX

MOV DX,SI;制成一个字符表以便查找。

RET

ERROR:LEA DX,D3 ;将D3表示的相对地址送DX

RET

LOCATE ENDP

DISPLAY PROC NEAR

MOV AH,09H;将找到的缩写字母在屏幕上显示出来

INT 21H

RET

DISPLAY ENDP

C ENDS

END START

方法2:数据表的制定与方法1有所不同

D SEGMENT

D1 DB "Please input month from the keyboad",0DH,0AH,"$" D2 DB 4, ?,3 DUP(?) ;准备接收键盘输入,只输入2个字符,为什么必须设定最大输入字符数为3,算回车符吗?

D3 DB "ERROR",0DH,0AH,"$"

MONTH1 DB 01H

DB "JAN",0DH,0AH,"$"

MONTH2 DB 02H

DB "FEB" ,0DH,0AH,"$"

MONTH3 DB 03H

DB "MAR" ,0DH,0AH,"$"

MONTH4 DB 04H

DB "APP" ,0DH,0AH,"$"

MONTH5 DB 05H

DB "MAY" ,0DH,0AH,"$"

MONTH6 DB 06H

DB "JUN" ,0DH,0AH,"$"

MONTH7 DB 07H

DB "JUL" ,0DH,0AH,"$"

MONTH8 DB 08H

DB "AUG" ,0DH,0AH,"$"

相关文档
相关文档 最新文档