学院:计算机科学与技术 专业:计算机科学与技术 班级:计科131
姓名 | 学号 | 实验组 | ||||
实验时间 | 指导教师 | 肖敏 | 成绩 | |||
实验项目名称 | 实验五:8086 汇编语言子程序程序设计 | |||||
实验目的 | 熟悉子程序的设计方法 | |||||
实验原理 | 对汇编源程序进行汇编、链接,在Debug环境下完成调试和运行。 | |||||
实验内容 | 1、熟悉子程序的结构及注意事项 2、掌握子程序的设计、调试方法 | |||||
实验环境 | 1. 硬件:微型计算机1台 2. 软件:MASM软件 | |||||
实验步骤 | 实验一. 使用子程序设计编程实现求数组ARY 元素之和: 编辑下面的源程序到文件lab5.asm 中: CODE SEGMENT ORG 100H ASSUME CS:CODE,DS:CODE,SS:CODE MAIN PROC FAR MOV AX,CODE MOV DS,AX MOV TABLE ,OFFSET ARY MOV TABLE+2,OFFSET COUNT MOV TABLE+4,OFFSET SUM MOV BX,OFFSET TABLE CALL PROADD MOV AX,4C00H INT 21H MAIN ENDP PROADD PROC NEAR PUSH AX PUSH CX PUSH SI PUSH DI MOV SI,[BX] MOV DI,[BX+2] MOV CX,[DI] MOV DI,[BX+4] XOR AX,AX NEXT:ADD AX,[SI] ADD SI,2 LOOP NEXT MOV [DI],AX POP DI POP SI POP CX POP AX RET PROADD ENDP ARY DW 1,2,3,4,5,6,7,8,9,10 COUNT DW 10 SUM DW ? TABLE DW 3 DUP(?) CODE ENDS END MAIN 使用相应的文本编辑器建立文件LAB5.asm,内容如上所示。 二. 生成可执行文件: 1.汇编: C:\\masm> masm lab5; 2.连接: C:\\masm> link lab5; 三. 请写出此程序中的变量ary,count,sum 的EA,并判断此程序的功能: 四. 用debug 调试此程序时,第一条指令的段内EA 是多少?此程序数据段内偏移地址为0 的字单 元数据为多少?其对应的机器指令是什么? -L ;加载程序文件lab5.exe -R ;查看IP 与CS 寄存器的内容 -D DS:0 ;查看当前数据段内偏移地址为0 的字单元数据 -U ;查看机器指令 实验二:编写一个子程序,实现在屏幕的指定位置,用指定颜色,显示一个用0 结尾的字符串 源程序如下 data segment str db 'display string',0 data ends code segment assume cs:code,ds:data start: mov ax,data mov ds,ax mov dh,8 mov dl,21 mov cl,3 mov si,offset str call show_str mov ax,4c00h int 21h ;---------------------------- show_str proc near push ax push cx push dx push es push si push di mov ax,0b800h mov es,ax dec dh mov al,160 mul dh add dl,dl mov dh,0 ;计算显示在屏幕位置 add ax,dx mov di,ax mov ah,cl x: mov cl,ds:[si] mov ch,0 jcxz f mov al,cl mov es:[di],ax inc si inc di inc di jmp x f: pop di pop si pop es pop dx pop cx pop ax ret show_str endp ;------------------------ code ends end start 实验三:编写一个子程序,实现将word 型数据以十进制形式显示出来 源程序如下: assume cs:code data segment db 10 dup(0) data ends stack segment db 16 dup(0) stack ends code segment start: mov ax, data mov ds, ax mov ax, stack mov ss, ax mov sp, 16 mov dx, 0c1h mov ax, 76f3h mov si, 0 call dwtoc mov dh, 8 mov dl, 3 mov cl, 2 call show_str mov ah, 01h int 21h mov ax, 4c00h int 21h; 子程序:dwtoc ; 功能:将dword型数据转变成表示十进制的字符串,字符串以0结尾 ; 参数:(ax) = dword 型数据的低16位 ;(dx) = dword型数据的高16位 ;ds:si 指向字符串首地址 ; 返回:无 dwtoc: mov cx, 0 push cx s_dwtoc: mov cx, 10 ; 除数 call divdw ; 余数在cx中 add cx, 30h push cx ; 保存余数的ASCII形式 ; 判断是否商为0,如果高低16位都为0,则返回 mov cx, dx jcxz ok_dxz; ; 高位不为0,则直接跳回,继续执行运算 jmp short s_dwtoc ; 商的高位为0 ok_dxz: mov cx, ax jcxz ok_axz jmp short s_dwtoc ; 商的低位为0 ok_axz: ; 赋值到 ds:[si] mov dx, si ; 保存si,si为字符串的首地址 loop_dtoc: pop cx mov ds:[si], cl jcxz end_dwtoc inc si jmp short loop_dtoc mov si, dx end_dwtoc: mov si, dx ret dtoc: ; 先把一个0放进堆栈,在后面s2从堆栈中取出的时候,可以根据cx为0跳转 mov cx, 0 push cx s1_dtoc: mov dx, 0 mov cx, 10 div cx mov cx, dx ; dx余数 add cx, 30h push cx ; 保存在堆栈 mov cx, ax ; ax为商,当商为0的时候,各位的值就已经得到了,就可以跳出循环 jcxz ok1_dtoc jmp short s1_dtoc ok1_dtoc: mov ch, 0 s2_dtoc: ; 从堆栈中取出 pop cx jcxz ok2_dtoc mov ds:[si], cl inc si jmp short s2_dtoc ok2_dtoc: ret show_str: push ax push bx push cx push dx push es push si ; 计算好字串开始显示的地址Y = 160*(行数-1) + 列数*2-2, B800 : Y ; 循环将参数里的字串写进显卡内存,并检测到0就返回 ; bx = 160*(行数-1) mov bh, dh sub bh, 1 mov al, 160 mul bh mov si, ax ; si 为根据行数算出来的偏移值 ; ax = 列数*2-2 mov bl, dl mov al, 2 mul bl sub ax, 2 ; 根据列数算出来的偏移值 add si, ax ; 行数和列数的和存在SI中了 mov ax, 0b800h mov es, ax mov bx, si ; 将si 的值保存在bx中,bx为显存显示偏移值 mov si, 0 ; 题目要求。。 mov dl, cl ; 保存字体颜色属性 mov ch, 0 s: mov cl, ds:[si] mov es:[bx], cl jcxz ok mov es:[bx+1], dl inc si add bx, 2 jmp short s ok: pop si pop es pop dx pop cx pop bx pop ax ret ; 子程序:divdw ; 要求:进行不会除法溢出的除法运算,被除数为dword,除数为word,结果为dword ; 参数:(ax) = 被除数dword型的低16位 ; (dx) = 被除数dword型的高16位 ; (cx) = 除数 ; 返回:(dx) = 结果的高16位 ; (ax) = 结果的低16位 ; (cx) = 余数 divdw: mov bx, ax ; 缓存ax——被除数的低16位 mov ax, dx ; ax = H, 被除数的高16位 mov dx, 0 div cx ; ax 为商,dx为余数 = rem(H/N) * 65536 push ax ; 结果的商,也就是最后要放在dx中的 mov ax, bx ; dx为 rem(H/N) * 65536, 为高16位,ax为低16位,再进行一次除法运算 div cx ; ax 为商——最后结果的低16位,dx为余数——为最后结果,应赋给cx mov cx, dx pop dx ret code ends end start | |||||
实验结果 | 实验一:变量ary,count,sum 的EA分别是00140,00154,00156此程序的功能是数列求和 实验二: 实验三: | |||||
实验总结 | 这次实验,感觉难度最大的就是做2个子程序的设计,在网上向好友请教了N回!还犯了一些低级的错误,如将16位的寄存器的内容传送到字符型数字串里去,这很明显是不对的,在逆序时寄存器的高16位会直接把正常的数字字符冲掉,还有就是将当我直接将字型单元的内容传送字型单元时,编译器会报错,不过提示是它后面的指令错误。转换后的数字串的末尾如果不是0的话,在调用输出子程序时会出现BUG,于是又在转换子程序里加了条指令,在第一次转换出来后,在数字串的末尾添加一个终止标志0。 | |||||
指导教师意见 | 签名: 年 月 日 |