合肥学院微机实验4(子程序调用实验代码及解析)

合肥学院微机实验4(子程序调用实验代码及解析),第1张

BUFFER DB 10 DUP(?)BUFFER存放8个不确定数

augend DB 2 DUP(?)被加数

addend DB 2 DUP(?)加数

msg1DB 0DH,0AH,'请输入被加数: $'

msg2DB 0DH,0AH,'请输入加数: $'

msg3DB 0DH,0AH,'结果:$'msg3存放结果

0DH和0AH分别是回车和换行的ASCII码,

'$'是DOS功能调用INT 21H中肢纤辩9号功能要求的要显示字符串的结束标志

.CODE

START: MOV AX,@DATA

MOV DS,AX

MOV ES,AX

CLD 方向标志位清零 CLD与STD是用来 *** 作方向标志位DF(Direction Flag)。

CLD使DF复位,即DF=0,STD使DF置位,即DF=1.用于串 *** 作指令

NOP 空 *** 作 NOP指令只使程序计数器PC加1,所以占用一个机竖枣器周期

其目的为保证写、读之间有个稳定时间

MOV AH,00H

MOV AL,03H

INT 10H 清屏

START1: MOV AH,09H 9号调用DX指向被加数的首地址,输出提示信息

LEA DX,msg1将源 *** 作数给出的有效地址传送到指定的的寄存器中

INT 21H

LEA DI,augend DI->augend的首地址

MOV CX,4按键次数

CALLGetBCDKey 得到双字节十进制数(被加数)

JNB START2 没有输入任何数字,结束 CF=0

MOV AH,09H 9号调用DX指向加数的首地址

LEA DX,msg2将源 *** 作数给出的有效地址传送到指定的的寄存器中

INT 21H

LEA DI,addend di指向加数

MOV CX,4按键次数

CALLGetBCDKey 得到双字节十进制数(加数)

JNB START2 没有输入任何数字,结束

MOV AL,augend 被加数的低8位送al

ADD AL,addend al与加数的低位相加的结果送al

DAA BCD算术运算调整,转换为压历缺缩型BCD

XCHGAL,AH 高位与低位互换

MOV AL,augend + 1

ADC AL,addend + 1 高位

DAA

XCHGAL,AH

MOV BL,0

ADC BL,0进位 bl存放的是进位 bl和ax相加是最后的结果

STD 方向标志置1

LEA DI,BUFFER+4 存放显示结果

CALLB1toB2 低位

MOV AL,AH

CALLB1toB2 高位

MOV AL,BL

OR AL,30H 转换成数字

STOSB 存数

LEA SI,BUFFER

MOV CX,5

CALLBlackDisplay将高位0消隐

MOV AH,09H

LEA DX,msg3 9号调用DX指向结果的首地址

INT 21H

MOV AH,09H

LEA DX,BUFFER 9号调用DX指向BUFFER的首地址

INT 21H

JMP START1 跳转到START1

START2: MOV AH,4CH 结束程序

INT 21H

JMP $

将一个字节压缩BCD码转换成二个字节数字

B1toB2 PROCNEAR段内

PUSHAX ax存放的是相加后的结果

AND AL,0FH 高四位置0

OR AL,30H 加30H

STOSB 存数 个位 百位

POP AX

AND AL,0F0H 低四位置0

ROR AL,4循环右移4位

OR AL,30H 加30H

STOSB 存数 十位 千位

RET

B1toB2 ENDP

BlackDisplayPROCNEAR

CLD方向标志清零

MOV DI,SI si送给di si指向buff的第一个缓冲区 增量变化

BlackDisplay1: LODSB 将高位0消隐,取串

CMP AL,'0'

JNZ Exit 若al不等于0跳转EXIT

LOOPBlackDisplay1否则cx不为0一直循环 cx次

INC CX cx加1

Exit: DEC SI si前移

REP MOVSB重复传送字节

MOV AL,'$' 把$符送al

STOSB存数

RET

BlackDisplayENDP

GetBCDKey PROCNEAR

LEA SI,BUFFER

MOV AL,4 把4写入到buff

MOV [SI],AL 【】是内存单元

MOV DX,SI

MOV AH,0AH dx指向缓冲区

MOV AL,02H 0:任意字符 1:16进制数 2:10进制数,10进制数输入

INT 21H

GetBCDKey1: LODSBds:si->al

AND AL,0FH 高4位清零

CMP CX,1

JE GetBCDKey2

DEC CX 进数位-1

MOV AH,AL

LODSB

AND AL,0FH

SHL AL,4 逻辑左移4位

OR AL,AH

GetBCDKey2: CLD

STOSB 存串指令

STD

LOOPGetBCDKey1 cx=2 原先为4 上面减了一次一 loop再减一所以等于2

MOV CL,[BUFFER]

SUB CL,[BUFFER+1]

SHR CL,1逻辑右移1位

MOV AL,0

CLD

REP STOSB 重复存数

STC进位标志位置1

RET

GetBCDKey3: CLC 进位标志位清零cf=0

RET 返回

GetBCDKey ENDP

西安邮电学院

微机原理实验报告

题 目: 宏指令及子程序设计实验

院系名称: 班 级: 学生姓名:

学号(8位):

指导教师:

2.5 宏令及子程序设计实验

2.5.1 实验目的

1、熟悉宏指令、宏定义、宏调用以及宏展开的概念;掌握宏指令的定义与调用的方法。 2、掌握子程序的定义、调用以及调用程序与子程序之间参数的传递方法。 3、了解宏指令与子程序的异同以及各自的适用场合。

2.5.2 实验预习要求

1、复习宏指令的定义与调用方法。 2、复习过子程序的定义与调用方法。

3、根据“2.5.3 实验内容”中给出的流程图和程序框架编写源程序,以便上机调试。 4、从“2.5.4 实验习题”中任选一道题目,编写源程序,以便上机调试。

2.5.3 实验内容

从键盘输入10个无符号十进制数(小于256),将其转换为二进制数并存放在NUM 字节型变量中,找出其中的最大数,并将找出的最大数在屏幕上显示出来。

要求:

① 在屏幕上显示字符串提示信息的功能由宏指令DSTRING 实现;稿袭饥

② 将键盘输入的十进制数转换成二进制数由子程序DTOB 实现;

③ 在N 个无符号字节型二进制数中找出最大数的功能由子程序FMAX 实现;

④ 将一个无符号字节型二进制数转换为十进制数并在屏幕上显示的功能由子程序BTOAD 实现。

程序运行结果如右图所示。 1、编程指导

(1)显示提示信息的宏指令DSTRING 的编写

宏指令通常用于在程序中需要反复使用但所需指令条数又不是很多的情形;而对于需要经常使用且需要较多指令才能完成的功能通常通过子程序调用来实现。这是因为,从执行速度上看,由于子程序调用涉及到保护断点的 *** 作,因此,子程序调用比宏调用执行时间相对要稍长一些;但从生成的可执行文件的大小方面考虑,子程序调用生成的文件要小一些。读者在进行汇编语言程序设计时,应综合考虑两者的利弊,以便进行合理选择。

下面给出实现提示信息显示的宏指令的定义:

DSTRING MACRO STRING PUSH DX PUSH AX MOV DX,OFFSET STRING MOV AH,09H INT 21H POP AX POP DX ENDM

请读者注意,禅悄宏指令应该先定义,后调用。因此,

宏定义通常紧跟在代码段中段寄存器赋值指令之

后键返给出。

(2)将键盘输入的十进制数转换为二进制数的子程序DTOB 的编写

子程序的定义方法请参阅教材“5.6.4 子程序设计”一节。将十进制数转换为二进制数的程序代码请参阅本书“2.4.3 实验内容”中“编程指导”部分。

(3)在N 个无符号字节型二进制数中找出最大数的子程序FMAX 的编写

请参阅教材“5.6.3 循环程序设计”一节例5.12。

(4)将一个无符号字节型二进制数转换为十进制数并在屏幕上显示的子程序BTOAD 的编写

程序代码请参阅本书“2.4.3 实验内容”中“编程指导”部分。 2、程序框架

COUNT EQU 10 DATA SEGMENT

NUM DB 10 DUP(?) IBUF DB 7,0,6 DUP(?) OBUF DB 6 DUP(?) INFOR1 D B "Please input 10 numbers:",0AH,0DH,"$" INFOR2 D B "The max found in the 10 numbers is $" INFOR3 D B 0AH,0DH,"$"

DATA ENDS

STACK SEGMENT stack

DA TA2 DW 40 DUP(?) TOP EQU LENGTH DATA2

STACK ENDS

CODE SEGMENT

ASSUME CS:CODE,DS:DATA,SS:STACK

start: MOV AX,DA TA

MOV DS,AX MOV AX,STACK MOV SS,AX MOV AX,TOP MOV SP,AX

DSTRING INFOR1 MOV BX,OFFSET NUM MOV CX,COUNT

LOOP1: CALL

DTOB

DSTRING INFOR3 MOV [BX],AL INC BX LOOP LOOP1

MOV AX,OFFSET NUM MOV CX,COUNT CALL FMAX DSTRING INFOR2 CALL BTOAD MOV AH,4CH INT 21H

CODE ENDS E ND

start

2.5.4 实验习题

1、从键盘输入N 个十进制数,求它们的和(累加和要求不大于65535),并将累加结果在屏幕上显示出来。要求给出必要的提示信息(用宏调用完成);累加功能由子程序调用实现;二进制数形式的累加和转换为十进制数并显示由子程序调用实现。 程序代码:

DA TA SEGMENT NUM DB 10 DUP(?) 用来存N 个数(二进制)小于一个字节 N DB ? 用来存N 的值 IBUF DB 7,0,6 DUP(?) 用来将十进制转换为二进制 OBUF DB 6 DUP(?) 用来将二进制转换为十进制 INFOR1 D B "Please input the N:$" INFOR2 DB 0AH,0DH,"Please input the numbers:",0AH,0DH,"$" INFOR3 D B 0AH,0DH,"The sum is: $" INFOR4 D B 0AH,0DH,"$" DA TA ENDS

CODE SEGMENT ASSUME CS:CODE,DS:DATA START: MOV AX,DA TA MOV DS,AX

DSTRING MACRO STRING 宏定义 PUSH DX PUSH AX

MOV DX,OFFSET STRING MOV AH,09H INT 21H POP AX POP DX ENDM DSTRING INFOR1 MOV

AH,01H

INT 21H SUB A L,30H MOV N,AL DSTRING INFOR2 MOV BX,OFFSET NUM MOV CL,N MOV CH,0 LOOP1:PUSH CX CALL DTOB DSTRING INFOR4 MOV [BX],AL INC BX POP CX

LOOP LOOP1 MOV SI,OFFSET NUM MOV CL,N CALL XADD DSTRING INFOR3 CALL BTOAD JMP T2

DTOB:MOV DX, OFFSET IBUF 键入一个十进制数(

XADD:MOV AX,0 T1:MOV BL,[SI] 使程序可以算出大于一个字节的数 MOV BH,0 ADD AX,BX INC SI LOOP T1 RET

BTOAD:MOV B X, OFFSET OBUF+5 MOV BYTE PTR [BX],"$"

MOV CX, 10 做(DX ):(AX )/10运算 LOOP2:MOV DX, 0 被除数高16位清0 DIV CX ADD DL, 30H 将DL 中的一位十进制数转换为ASCII 码 DEC BX MOV [BX], DL OR AX, AX JNZ LOOP2 判断商是否为0,不为0继续 MOV DX, BX MOV AH, 09H INT 21H 显示转换得到的十进制数 RET T2:MOV AH,4CH INT 21H CODE ENDS END S TART 程序流程图:

实验中遇到的问题:

1, 当相加结果大于一个字节所能表示的范围时,输出结果错误 2, 不同字长的数相加结果不一样,容易混淆

解决方法:

用更多的字节来存储结果,相加是让两个数的字长一致

2.5.5 实验报告总结

1、补全“2.5.3 实验内容”中源程序框架内未写出的程序代码,并说明你在调试该程序过程中遇到了哪些问题,是如何处理的?若允许输入大于255小于65536的十进制数,程序应如何修改? 答:修改存储数据的字节数,使其能存储大于255的数值,如DW 。 2、写出实验小结,内容包括实验心得(收获)、不足之处或今后应注意的问题等。 掌握宏指令的定义和使用方法。学会根据不同的数值选用不同大小的空间来存储。 掌握数值的输入和输出,以及不同大小的数值怎样存储,怎样运算

data segment

string db 'abc$'

text db '或并hiaabckabiiabcyyfabcds$'

output db 'count=$'

count db 3

db ?

db 3 dup(?)

data ends

code segment

assume cs:code,ds:data

start: mov ax,data

mov ds,ax

mov bx,offset count

mov cl,0

mov si,offset string

mov di,offset text

mov al,[si]

l0: mov ah,[di]

cmp ah,'$'

jz l4

cmp ah,al

jz l1

inc di

jmp l0

l1: inc si

inc di

mov al,[si]

mov ah,[di]

cmp al,'$'

jz l3

cmp ah,'$'

jz l4

cmp ah,al

jnz l5

jmp l1

l3: inc cl

l5: mov si,offset string

mov al,[si]

jmp l0

l4: mov ah,09h

mov dx,offset output

int 21h

mov dl,0dh 回车

mov ah,02h

int 21h

mov dl,0ah 换行

mov ah,02h

int 21h

add cl,30h

mov [bx],cl

inc bx

mov ah,'$'枝液

mov [bx],ah

mov ah,09h

mov dx,offset count

int 21h

mov ah,4ch

int 21h

code ends

end start

微机猛团物作业还是自己动手比较好


欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/yw/12481644.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023-05-25
下一篇 2023-05-25

发表评论

登录后才能评论

评论列表(0条)

保存