微机原理实验1

  • 格式:doc
  • 大小:808.00 KB
  • 文档页数:23

信息与通信工程学院微机原理软件实验报告(二)班级:姓名:学号:序号:日期:2014年12月一、实验目的1)掌握MASM 的操作步骤,能够将源程序编译成可执行文件2)掌握简单的DOS功能调用3)掌握简单的汇编语言程序的设计二、实验任务1. 编一程序,在显示器上显示256个ASCII代码,要求显示格式为每行显示16个字符,两个ASCII字符间空一格。

2. 试编一程序,把地址偏移量为100H 单元开始的256 个单元分别写入:00H,01 H,02H,03H,…,FFH 数据。

统计写入的数据块中0 元素、正元素、负元素的个数,并分别把统计结果送人上述数据块之后的三个单元中。

用DOS功能调用显示上面两题中数据块各单元(包括统计结果)内容。

为了显示清晰明了,要求每行显示16 个数据,两个数据之间用空格分开。

(教材P185第1、2、3题合到一起编一完整的程序。

)3. 编一程序,把键入的十六进制数转换成十进制数并在屏幕上显示出来。

键入的最大数为FFFFH,若键人的不是十六进数字,则显示出错提示。

(教材P188第21题。

)三、实验内容1.显示256个ASCII码(1)源程序(附注释):data segment ;定义数据段buf db 256 dup (?)count equ $-buf ;将buf定义的字节长度赋值给count data endscode segment ;定义代码段assume ds:data,cs:codestart: mov ax,datamov ds,axmov si,offset buf ;设置数据块首地址mov cx,count ;设定循环次数cld ;地址修改为增量xor ax,axxor dx,dxxor bx,bxhyone: mov [si],al ;将数据存入数据段inc siinc alloop hyonemov si,offset buf ;指向数据块首地址mov cx,count-1hytwo: mov dl,[si] ;显示数据段的内容mov ah,2int 21hmov dl,20h ;插入空格mov ah,2int 21hinc siinc bl ;设定为换行指示标志cmp bl,10h ;当显示了16个字符之后就换行jz hythreeloop hytwo;回车换行hythree: mov dl,0dhmov ah,02hint 21hmov dl,0ahmov ah,02hint 21hxor bl,bl ;将换行指示标志重新置为0cmp cx,0 ;判断是否显示完jnz hytwo ;没有显示完的话继续显示jz hyfour ;显示完结束程序hyfour:mov ah,4ch ;终止程序int 21h code endsend start(2)程序流程图: 开始初始化代码段,程序段基址设置存入数据循环次数cx 和初始ASCII 码blbh 作为每一行显示字符个数的界限;Dos 功能调用显示bl结束Bl 加1,bh 减1Bh 为0换行Cx 减1Cx 为0是否是否图12. 写入数据,统计各类元素个数(1)源程序(附注释):data segment ;定义数据段org 100h ;设定初始偏移量为100hbuf db 259 dup(?) ;定义259个数据存放地址count equ $-buf ;将buf定义的字节长度赋值给count hy db 0 ;定义变量hy作为空格显示控制标志data endscode segment ;定义代码段assume cs:code,ds:datastart: mov ax,datamov ds,axmov si,offset buf ;设置数据块首地址mov cx,count-3 ;将循环次数存入cx中cld ;地址修改为增量xor bx,bxxor ax,axxor dx,dxhyone: mov[si],al ;将数据存入数据段inc siinc alloop hyonemov si,offset buf ;指向数据块首地址mov cx,count-3 ;将循环次数存入cx中lodsb ;把si指向的存储单元读入累加器hytwo: mov al,[si]and al,aljz zero ;如果为0的话则跳转到zerojns positive ;如果大于0的话则跳转到positivejs negtive ;如果小于0的话则跳转到negtive zero: inc bl ;统计为0的个数,用bl计数jmp hythreepositive: inc bh ;统计大于0的个数,用bh计数jmp hythreenegtive: inc dl ;统计小于0的个数,用dl计数jmp hythreehythree: inc si ;si加一loop hytwo ;继续判断下一个数hyfour: dec si ;先执行后判断所以si要减1;将0的个数存入数据块之后的第一个单元mov [si],blinc si;将大于0的个数存入数据块之后的第二个单元mov [si],bhinc si;将小于0的个数存入数据块之后的第三个单元mov [si],dlmov si,offset buf ;指向数据块首地址mov cx,count ;设置循环次数done: mov al,[si] ;将数据段的内容赋值给almov bh,al ;暂存数据;右移4位shr al,1shr al,1shr al,1shr al,1call dispmov al,bh ;将暂存的数据送回aland al,0fh ;屏蔽掉高四位call dispinc siloop donemov ah,4ch ;终止程序int 21hdisp proccmp al,0ah ;与0ah比较,小于0ah,加30hjs hyfive ;大于0ah,为十六进制数A~F,加37hadd al,7hyfive: add al,30hmov dl,al ;dos功能调用显示字符mov ah,02int 21hinc hycmp hy,02jz hysevenret;根据空格显示标志符hy的大小判断是否插入空格hyseven: mov dl,20h ;插入空格mov ah,2int 21hinc dhmov hy,0cmp dh,10hjz hysixrethysix: mov dl,0dh ;回车换行mov ah,02hint 21hmov dl,0ahmov ah,02hint 21hxor dh,dhretdisp endpcode endsend start(2)程序流程图开始初始化代码段,程序段,堆栈段基址设置存入数据循环次数cx和初始存入数据blBl与0比较比零大,则存正数内存单元加1为0,则存零内存单元加1比零小,则存负数数内存单元加1数据Bl加1内存单元地址加1Cx减1Bl存入数据内存单元Cx为0显示信息提示部分内存单元地址指向259个数据Cx置为259显示数据高四位显示数据低四位换行Cx减1内存地址si加1一行数据为16个Cx减1内存地址si加1 Cx为0结束>0<0=0是否是否图23. 十六进制数转换成十进制数(1)源程序(附注释):name hexdeccode segmentassume cs:code;提示信息msg1 db 'erro number','$'msg2 db 'Hello! Please input the hexadecimal number:','$'msg3 db 'Hello! To exit this program,you only have six chances','$' msg4 db 'number overflow','$'hy db 0count db 0crlf macro ;定义宏指令,回车换行mov dl,0dhmov ah,02hint 21hmov dl,0ahmov ah,2int 21hendmstart: mov ax,seg codemov ds,ax ;给数据段赋值,与代码段在同一个段;提示正确调试的机会只有6次begin: crlfmov dx,offset msg3mov ah,09int 21hcrlfmain: crlfmov dx,offset msg2 ;提示输入一个十六进制的数mov ah,09int 21hcrlfcall hexbin ;从键盘接收进制的数并转化为二进制crlfcall bindec ;把二进制转化为十进制数crlfmov hy,0 ;重置输入次数标志inc count ;正确调试次数加1cmp count,6 ;如果已经正确调试六次则退出程序jz donejmp maindone: mov ah,4ch ;退出程序int 21h;接收键盘输入的十六进制数据,并转化为二进制子程序hexbin proc nearxor bx,bxnewchar: mov ah,01int 21hcmp al,0dh ;若输入回车则结束本程序jz retu;统计输入的十六进制数长度,如果大于ffffh则溢出报错inc hycmp hy,5jz bck ;溢出报错sub al,30hjl exit ;键入的字符小于0,为非法字符cmp al,9jle addto ;键入的字符大于0,小于9,移位处理sub al,07 ;判断是否为字母A~Fcmp al,0ah ;不是大于A的字母为非法字母jl exitcmp al,0fh ;判断是否为a~fjg nextaddto: mov cl,4shl bx,cl ;键入的字符左移四位,先键入的字符移向高位mov ah,0add bx,ax ;把刚键入的字符与前面的字符和在一起jmp newchar;溢出报错bck: mov hy,0xor bx,bxxor ax,axcrlfmov dx,offset msg4mov ah,09int 21hcrlfjmp mainnext: sub al,20h ;判断是否为小写a~fcmp al,0ahjl exit ;小于a为非法字符cmp al,0fh ;大于f为非法字符jle addtojg exitjmp returetu: ret;输入的不是16进制数,报错exit: crlfmov dx,offset msg1mov ah,09int 21hcrlfjmp newcharhexbin endp;把二进制数转换为十进制数bindec proc nearmov cx,10000call hyfinal ;键入的数含有几个万位mov cx,1000call hyfinal ;键入的数含有几个千位mov cx,100call hyfinal ;键入的数含有几个百位mov cx,10call hyfinal ;键入的数含有几个十位mov cx,1call hyfinal ;键入的数含有几个个位retbindec endphyfinal proc nearmov ax,bx ;被除数的低十六位在ax中mov dx,0 ;被除数的高十六位在dx中div cxmov bx,dx ;余数在dx中,送入bxadd al,30hmov dl,al ;显示商al,即转换后的十进制数mov ah,2int 21hrethyfinal endpcode endsend start(2)程序流程图:开始寄存器清零初始化读入键入数据是否为回车Bx 赋给ax返回主程序读入数据减去30h与0比较执行tishi显示输入数据格式错误与9比较Bx 乘以权值16累加al 与0Ah 比较减去07h与0Fh 比较减去20h与0ah 比较与0fh 比较是否<0>=0>9<9>0Ah<0Ah>0Fh<0Fh >0ah<0ah<0fh >ofh图3四、实验结果1.显示256个ASCII码(1)编译t1.asm,生成t1.obj和t1.exe,如图:(2)运行t1.exe,输出256个ASCII码,每16个为一行,运行结果如下:2. 写入数据,统计元素个数(1)编译t2.asm,生成t2.obj和t2.exe,如图所示(2)运行t2.exe,前256位输出为00h~FFh数据,后3位输出为统计正,零,负结果,运行结果如图所示3. 十六进制数转换成十进制数(1)编译t3.asm,生成t3.obj和t3.exe,如图所示(2)基础功能:运行t3.exe,首先输出提示信息,提示输入一个十六进制的数,并将输入十六进制转化为十进制,支持a~f大写和小写输入。