装潢设计公司排行长春seo排名
实验内容
1. 从数据段DS中包含9个字节的数组数据VALUE中分别找出最大值(存到max中)、最小值(存到min中)。
2. 能够单步执行程序,认真观察、判断每条指令执行的结果是否正确,对错误结果,能够做出相应的处理。
实验步骤
(1)启动“emu8086”软件。
(2)输入源程序并存盘为*.asm文件。
(3)编译、链接、运行程序并查看实验结果。
(4)实验报告要求附上程序代码,并记录运行结果。
模拟C语言的for循环遍历数组,比对最大值最小值
程序代码
code1
这段程序是边检索边手搓的,不会将字符显示在显示屏上
DATAS SEGMENT ;定义数据段X DW 5,2,3,4,12,6,7,8,9,5 ;定义10个数MAX DW ? ;存放最大值MIN DW ? ;存放最小值,定义成? 不确定大小
DATAS ENDS ;定义数据段结束 ends与segment成对出现 STACK SEGMENT ;定义堆栈段;DW 20 DUP(0) ;为堆栈段分配空间
STACK ENDS ;定义堆栈段结束CODE SEGMENT ;定义代码段ASSUME CS:CODE, DS:DATAS, SS:STACK ;告诉编译器将段寄存器与符号对应起来
START: ;程序入口 起始地址标号,名称可以自己取MOV AX, DATAS ;取DATA段地址给AXMOV DS, AX ;将段地址DATAS送入DS中 初始化DS段地址,建立CS与DS段联系 MOV DI,OFFSET X ;DI 变址寄存器 ,取X地址?MOV AX,[DI] ;将段地址为 DS 偏移地址为 DI 的内存单元中的值移入 AX 中MOV MIN,AX ;存第一个数,当做默认最大值MOV MAX,AX ;存第一个数,当做默认最小值MOV CX,9 ;设定循环次数9, 一共10个数,减去一个默认值,还需要循环9次Loop_Max_Min: ;循环判断最大值、最小值INC DIINC DI ;DI += 2,DW类型,一个字=两个字节,所以要加两次MOV AX, [DI];将段地址为 DS 偏移地址为 DI 的内存单元中的值移入 AX 中 CMP AX, MAX ;CMP指令,不回送结果,只影响标志位状态JG MAX_Reload ;有符号AX>MAX, 跳转到 MAX_RELOAD CMP AX, MIN ;只影响标志位状态JL MIN_Reload ;有符号 AX<=MIN, 跳转到 MIN_ReloadJG LOOP_Judge ;加一句判断,比最大的小,比最小的大的情况,直接跳转到 Loop_Max_Min,避免顺序执行给MAX变量赋值!MAX_Reload:MOV MAX, AX ;将最大值赋值给MAXJMP LOOP_Judge ;跳转到判断是否继续循环MIN_Reload:MOV MIN, AX ;将最小值赋值给MINJMP LOOP_Judge LOOP_Judge: LOOP Loop_Max_Min ;判断CX,如果大于0就继续循环 MOV AH, 4CH ;返回DOS系统INT 21H
CODE ENDS ;定义代码段结束END START ;程序结束
复制代码,模拟,变量,运行
点击变量会弹出一个变量框
运行(run)
修改MAX和MIN的显示类型
数据段的定义:X DW 5,2,3,4,12,6,7,8,9,5 ;定义10个数
最大是12,最小是2
验证正确,代码没有问题~
code2
第二个思路
并且可以将最大值最小值输出在屏幕上
DATA SEGMENT ;数据段VALUE DB 13,8,36,66,56,65,12,15,24VALNUM EQU $-VALUE ;取地址$ P132 $- 是取长度MAX DB 0 ;定义最大值 8位数据MIN DB 0 ;定义最小值MAX1 DB 'MAX = $'MIN1 DB 'MIN = $' CHANGELINE DB 13,10,'$';用来表示换行符
DATA ENDS CODE SEGMENT ;代码段ASSUME CS:CODE, DS:DATA
START:MOV AX,DATAMOV DS,AXCLD ; DF=0LEA SI,VALUE ;取VALUE地址MOV AH,[SI] MOV MAX,AH ;赋初值MOV MIN,AHINC SIMOV CX,VALNUM-1 ;循环次数
NEXTMAX:LODSB ;串读取指令,将SI指向的内容读入AL,并且SI自加CMP AL,MAX ;与最大值比较JBE TOZUIXIAO ;小于等于最大值,跳转到和最小值比较MOV MAX,AL ;否则顺序执行,赋值给MAX
TOZUIXIAO:CMP AL,MIN ;和最小值比较JAE NEXT ;如果大于等于最小值,跳转到下一次循环MOV MIN,AL ;否则顺序执行,赋值给MIN
NEXT:LOOP NEXTMAX ;判断CX,如果大于0就继续循环 ;如果循环完成,就执行下面显示输出的语句 MOV DX,OFFSET MAX1 ;存放MAX1字符串偏移地址MOV AH,09H ;09H字符串输出 INT 21H MOV AL, MAX ;输出最大值,先将最大值赋值给ALCALL DISPLAY ;调用DISPLAY MOV DX,OFFSET CHANGELINE ;输出换行符MOV AH,9INT 21HMOV DX,OFFSET MIN1MOV AH,09HINT 21HMOV AL, MIN ;最小值赋值给ALCALL DISPLAY MOV AH,4CH ;返回DOSINT 21H;在屏幕上输出
DISPLAY:PUSH BX ;压入堆栈保护PUSH CX;数位分离,分别显示个位十位MOV AH,0MOV BL,10DIV BL ; AX/10,商送AL余数送AHXCHG AL,AH ;一条语句实现交换AL与AH内容OR AX,3030H ;或3030H,将数字转ASCII码MOV CX,AXMOV DL,CH ;AH送DLMOV AH,02H ;单字符显示DL的内容INT 21HMOV DL,CL ;AL送DLMOV AH,02H ;单字符显示DL的内容INT 21H POP CX ;先出POP BX
RETCODE ENDS
END START
- 编程思路:
寻找9个数的最大值最小值的思路,先用第一个数赋初始值,赋给MAX和MIN,取下一个数和最大值比较,如果小于等于最大值就跳转到比较最小的程序,否则赋值给MAX,在比较最小的程序里,如果大于等于最小,就执行下一次循环比较,否则赋值给MIN,依次循环遍历8次,即可找出最大值与最小值。- 程序编写:
段定义:段定义语句后面要加SEGMENT,段定义结束语句后面要加ENDS
定义变量:定义需要用到的变量,可以边写边定义。
段分配:用符号把段定义完成后还需要用ASSUME声明,将段寄存器与符号对应起来。
模块化:将输出显示的部分,封装成一个子函数。- Debug:
运行代码输出MAX=36MIN=36,输出显示有问题,可能是比较大小的程序部分出错,也可能是显示出错,再次运行代码,查看每个变量的值,发现MAX和MIN的数值是正确的,说明比较大小部分的代码正确,那问题就是显示输出有问题,既然能在终端显示36说明可以输出数字,只是输出的数字不对,查看代码,输出最大值最小值的时候,并没有赋要显示的值,在CALL DISPLAY语句前面加上要显示的变量即可。