汇编语言程序设计实验教程第二章实验报告实验2.1用表格形式显示字符1.题目:用表格形式显示ASCII字符SMASCII2.实验要求:按15行*16列的表格形式显示ASCII码为10H-100H的所有字符,即以行为主的顺序及ASCII码递增的次序依次显示对应的字符。
每16个字符为一行,每行中的相邻两个字符之间用空白符(ASCII为0)隔开。
3.提示:(1)显示每个字符可使用功能号为02的显示输出功能调用,使用方法如下:mov ah,02hmov dl,输出字符的ASCII码int 21h(2)显示空白符时,用其ASCII码0置入dl寄存器。
每行结束时,用显示回车(ASCII 为0dh)和换行符(ASCII为0ah)来结束本行并开始下一行。
(3)由于逐个显示相继的ASCII字符时,需要保存并不断修改dl寄存器的内容,而显示空白、回车、换行符时也需要使用dl寄存器,为此可使用堆栈来保存相继的ASCII字符。
具体做法是:在显示空白或回车、换行符前用指令push dx把dl的内容保存到堆栈中去。
在显示空白或回车、换行符后用指令pop dx恢复dl寄存器的原始内容。
4.程序清单:code segmentassume cs:codestart:mov dx,0010hnext:mov cx,10hloop1:mov ah,02hint 21hinc dxpush dxint 21hpop dxloop loop1push dxmov dl,0ahint 21hmov dl,0dhint 21hpop dxcmp dx,100hjb nextmov ah,4chint 21hcode endsend start5.运行结果如下:6.实验总结:通过本次实验我深刻的知道用汇编语言编译程序的方法,掌握了如何合理的利用各个寄存器进行程序的控制操作,初步了解到循环程序的控制方法,以及dos中断调用的基本要领对学习汇编语言有了非常好的帮助作用!汇编语言实验二查找匹配字符串一、目的查找匹配字符串SEARCH程序接收用户键入的一个关键字以及一个句子。
如果句子中不包含关键字则显示‘NO match!’;如果句子中包含关键字则显示‘MATCH’,且把该字在句子中的位置用十六进制数显示出来。
流程图三、设计和编码DATA SEGMENTmess1 DB 'Enter keyword:','$' mess2 DB 'Enter Sentence:','$'mess3 DB 'Match at location:','$'mess4 DB 'NOT MATCH.',13,10,'$'mess5 DB 'H if the sentence',13,10,'$'change DB 13,10,'$'stoknin1 label bytemax1 db 10act1 db ?stokn1 db 10 dup(?)stoknin2 label bytemax2 db 50act2 db ?stokn2 db 50 dup(?)DATA ENDSSTACKS SEGMENT;此处输入堆栈段代码STACKS ENDSCODE SEGMENT;*************************************代码段main proc farassume cs:code,ds:data,es:dataSTART:push dssub AX,AXsub BX,BXsub DI,DIsub SI,SIpush AX ;为返回dos并清空后面要用到的寄存器MOV AX,DATAMOV DS,AXLEA DX,mess1MOV ah,09INT 21h ;输出Enter keywordLEA DX,stoknin1MOV ah,0ah ;用21号中段的0ah号功能获取关键字INT 21hcmp act1,0je exit ;如果为空直接退出程序a10:;********************************输入Sentence并判断LEA DX,changeMOV ah,09INT 21h ;输出回程,换行LEA DX,mess2MOV ah,09INT 21h ;输出Enter Sentence:LEA DX,stoknin2MOV ah,0ahINT 21h ;用21号中段的0ah号功能获取句子MOV AL,act1CBWMOV CX,AX ;保存关键字长度到cxPUSH CX ;cx入栈MOV AL,act2cmp AL,0je a50 ;保存句子长度到al,若句子为空则跳转显示not matchSUB AL,act1js a50 ;若句子长度小于关键字长度,则跳转显示not matchINC ALCBWLEA BX,stokn2 ;将句子的首地址放进BXMOV DI,0MOV SI,0a20:;****************************************比较,内循环MOV AH,[BX+DI]CMP AH,stokn1[SI] ;遇见字符不相等就跳转到a30jne a30INC DIINC SIDEC CX ;没遇到一个相等的字符,cx-1,cx不为0则比较下一个字符,当cx为0是说明关键字比较完CMP CX,0je a40jmp a20a30:;*****************************************外循环,BX+1,清空si,di继续内循环比较INC BXDEC ALcmp AL,0je a50MOV DI,0MOV SI,0POP CXpush CXjmp a20a40:;*****************************************match,将bx减去句子的首地址加一得到关键字所在位置,调用二进制转十六进制子函数将位置输出SUB BX,offset stokn2INC BXLEA DX,changeMOV ah,09INT 21hLEA DX,mess3MOV ah,09INT 21hCALL btohLEA DX,mess5MOV ah,09INT 21hjmp a10;****************************************二进制转换十六进制btoh PROC NEARMOV CH,4rotate: MOV CL,4ROL BX,CLMOV AL,BLand AL,0fhadd AL,30hcmp al,3ahjl printitadd al,7hprintit:MOV dl,alMOV ah,2int 21hdec chjnz rotateretbtoh endpa50:;*****************************************显示not matchLEA DX,changeMOV ah,09INT 21hLEA DX,mess4MOV ah,09INT 21hjmp a10exit:retmain endpCODE ENDSEND START四、运行结果及分析五、实验小结六、附录(选)实验2.4查找电话号码一、实验目的与要求学习用汇编语言设计与编写子程序。
题目:查找电话号码phone二、实验内容(1) 要求程序建立一个可存放50项的电话号码表,每项包括人名(20个字符)及电话号码(8个字符)两部分;(2) 程序可接收输入人名及相应的电话号码,并把它们加入电话号码表中;(3) 凡有新的输入后,程序应按人名对电话号码表重新排序;(4) 程序可接收需要查找电话号码的人名,并从电话号码表中查出其电话号码,再在屏幕上以如下格式显示出来。
name tel.X X X X X X X X三、实验步骤1.设计分析1)根据题目要求必须要定义的空间:✧可存50个联系人的号码表✧姓名缓冲区✧号码缓冲区✧各种提示字符串2)为操作方便,多定义以下空间:✧tab_len用来记录联系人数目✧endaddr 用来记录最后一个联系人的地址+28✧temp 一个联系人记录的大小,用于排序时的缓存数据2.程序执行流程图3.模块层次图4.模块说明四、实验总结与体会。
先画好程序框图和模块调用图,并在编码中不断修改完善,对把握程序的整体结构很有帮助。
把模块设计成子程序在主程序调用,分解了整个程序功能,降低了设计的难度,同时方便调试和修改。
程序中添加适当的辅助变量,可以简化操作,如本程序设表长tab_len 和endaddr(电话表最后一个基址)方便排序、插入等操作。
程序需要良好的人机交互,应该有各种操作提示和警告信息。
程序中输入输出等要有容错处理,要能对各种可能情况作出反应。
使用跳转指令时应注意跳转是否超出范围,Jmp指令能够实现无条件远转移,但je,jb等条件转移指令只能段内短转移,如有需要可以跳转到一个地方再用jmp跳转。
使用循环结构时不要忘记了结束条件,导致死循环。
因为汇编接近机器语言,直接对内存操作,所以脑中要有内存单元,单元地址等的清晰概念和形象,对数据在内存中表示、各种寻址方式、各寄存器的用途、用法都应该相当熟悉。
汇编语言没有像其他高级语言的数据类型的概念,数据都是以二进制存储。
通过这个综合设计,对寄存器的默认组合、使用,常用指令,各种寻址方式基本能够熟练运用。
个人感觉汇编与其他高级语言的操作上的区别:汇编语言把每一步操作都细化。
所以写起来比较麻烦些,但只有想不到,没有做不到的,只要想的出来的,汇编应该都可以写出来。
程序调试主要是用debug。
Debug是个十分好用的工具,通过设置断点,可以调试任意程序任意部分,通过单步执行可以十分清楚各寄存器和地址单元的变化来找出错误。
五、源程序data segmenttel_tab db 50 dup( 28 dup(' ')) ; tel_tab电话本空间tab_len dw 0 ; 已存联系人数目endaddr dw 0 ; 最后一个联系人的地址+28 tname db 21,?,20 dup(' '),? ; 姓名缓冲区tphone db 9,?,8 dup(' '),? ; 号码缓冲区temp db 28 dup(?) ; 一个联系人的临时空间iname db 13,10,'Input name:',13,10,'$'iphone db 13,10,'Input a telephone number:',13,10,'$'go_on db 13,10,'Continue insert? <Y/N>',13,10,'$'; 提示是否继续插入联系人sname db 13,10,'Name?',13,10,'$'name_e db 13,10,13,10,'The name has been in the table! Please input again!',13,10,'$' text2 db 13,10,'Name Tel. ',13,10,'$'text3 db 13,10,'The name is not in the telephone table!',13,10,'$'text4 db 13,10,13,10,'Do you want a telephone number? <Y/N>',13,10,'$'data endscode segment; ****************************************************************************; 主程序; -------------------------------------------------------------------------------------main proc farassume cs:code ,ds:data,es:datastart:push ds ; 保存旧数据用于返回sub ax,axpush axmov ax,data ; 数据段、附加段初始化mov es,axinname: lea dx,iname ; 提示输入姓名mov ah,09hint 21hcall input_name ; 调用读入姓名子程序call name_search ; 调用查找子程序,cmp bx,-1 ; 如表中不存在该联系人je stor ; 则跳转到storcall crlf ; 回车换行lea dx,name_e ; 否则提示该联系人已在表中,提示重新输入mov ah,09hint 21hjmp innamestor: call stor_name ; 调用姓名转存子程序,把姓名移动到表中lea dx,iphone ; 提示输入电话号码mov ah,09hint 21hcall inphone ; 调用读入号码子程序call name_sort ; 排序call crlflea dx,go_on ; 提示是否继续插入mov ah,09hint 21hchoice1: mov ah,07 ; 读取用户选择int 21hcmp al,'y'je innamecmp al,'Y'je innamecmp al,'n'je print_all ; 如选择不插入,则显示所有记录cmp al,'N'je print_alljmp choice1print_all: call printall ; 显示所有记录want_search: call crlflea dx,text4 ; 提示是否查找号码int 21hcall crlfchoice2: mov ah,07 ; 读取用户选择int 21hcmp al,'y'je search ; 如果为y或Y则跳转到查找searchcmp al,'Y'je searchcmp al,'n' ; 为n或N则退出程序je exit_mcmp al,'N'je exit_mjmp choice2search: lea dx,sname ; 提示用户输入要查找的姓名mov ah,09int 21hcall input_name ; 读入姓名call name_search ; 查找call crlfcall crlfcmp bx,-1 ; 是否查找到?je not_find ; (bx)=1 则跳转到未找到not_findlea dx,text2 ; 找到则输出'Name Tel. 'mov ah,09int 21hcall printline ; 显示查找到的联系人jmp want_search ; 跳转到提示查找not_find: ; 未找到call crlflea dx,text3 ;输出'The name is not in the telephone table!'mov ah,09hint 21hjmp want_searchexit_m: retprintall proc near;**************************************************************************;显示所有电话。