一、实验目的
二、实验准备
三、实验结果
Task1
使用任何一款文本编辑器,录入8086汇编程序源码task1.asm。 实验代码:assume cs:code, ds:data data segment x db 1, 9, 3 len1 equ $ - x y dw 1, 9, 3 len2 equ $ - y data ends code segment start: mov ax, data mov ds, ax mov si, offset x mov cx, len1 mov ah, 2 s1:mov dl, [si] or dl, 30h int 21h mov dl, ' ' int 21h inc si loop s1 mov ah, 2 mov dl, 0ah int 21h mov si, offset y mov cx, len2/2 mov ah, 2 s2:mov dx, [si] or dl, 30h int 21h mov dl, ' ' int 21h add si, 2 loop s2 mov ah, 4ch int 21h code ends end start
问题1: line27, 汇编指令 loop s1 跳转时,是根据位移量跳转的。通过debug反汇编,查看其机器码,分析其跳转的位移量是多少?(位移量数值以十进制数值回答)从CPU的角度,说明是如何计算得到跳转后标号s1其后指令的偏移地址的。
根据076B:0019 E2F2 LOOP 000D E2(Loop指令)F2(位移量的补码)即位移量为(F2)补为14,结果为下一条1bh-0dh=0dh问题2:line44,汇编指令 loop s2 跳转时,是根据位移量跳转的。通过debug反汇编,查看其机器码,分析其跳转的位移量是多少?(位移量数值以十进制数值回答)从CPU的角度,说明是如何计算得到跳转后标号s2其后指令的偏移地址的。
根据076B:0037 E2F0 LOOP 0029 同上,(F0)补为16,39h-10h=29hTask2
使用任何一款文本编辑器,录入8086汇编程序源码task2.asm。 实验代码:assume cs:code, ds:data data segment dw 200h, 0h, 230h, 0h data ends stack segment db 16 dup(0) stack ends code segment start: mov ax, data mov ds, ax mov word ptr ds:[0], offset s1 mov word ptr ds:[2], offset s2 mov ds:[4], cs mov ax, stack mov ss, ax mov sp, 16 call word ptr ds:[0] s1: pop ax call dword ptr ds:[2] s2: pop bx pop cx mov ah, 4ch int 21h code ends end start① 根据call指令的跳转原理,先从理论上分析,程序执行到退出(line31)之前,寄存器(ax) = ? 寄存器(bx) = ? 寄存器(cx) = ? ax=21h; bx=26h; cx=076ch; call word 入栈下一条即s1的ip,出栈给ax; call dword指令依次入栈s2的cs和ip,ip出栈bx,cs出栈cx; ② 对源程序进行汇编、链接,得到可执行程序task2.exe。使用debug调试,观察、验证调试结果与理论分析结果是否一致。 一致;
Task3
编写8086汇编源程序task3.asm,在屏幕上以十进制形式输出data段中这一组连续的数据,数据和数据之间以空格间隔。 要求: 编写子程序printNumber 功能:以十进制形式输出一个两位数 入口参数:寄存器ax(待输出的数据 --> ax) 出口参数:无 编写子程序printSpace 功能:打印一个空格 入口参数:无 出口参数:无 在主体代码中,综合应用寻址方式和循环,调用printNumber和printSpace, 实现题目要求。 实验代码:assume ds:data, cs:code data segment x db 99, 72, 85, 63, 89, 97, 55 len equ $- x data ends data1 segment db 10 data1 ends code segment start: mov ax, data mov ds, ax mov si, offset x mov cx, len s1: mov ah, 0 mov al, ds:[si] div byte ptr ds:[10h] call printNumber call printSpace inc si loop s1 mov ax, 4c00h int 21h printNumber: mov bx, ax or bl, 30h or bh, 30h mov ah, 2 mov dl, bl int 21h mov dl, bh int 21h ret printSpace: mov ah, 2 mov dl, ' ' int 21h ret code ends end start运行结果:
Task4
编写8086汇编源程序task4.asm,在屏幕上以指定颜色、指定行,在屏幕上输出字符串。 要求: 编写子程序printStr 功能:在指定行、以指定颜色,在屏幕上显示字符串 入口参数 字符串首字符地址 --> ds:si(其中,字符串所在段的段地址—> ds, 字符串起始地址的偏移地址—> si) 字符串长度 --> cx 字符串颜色 --> bl 指定行 --> bh (取值:0 ~24) 出口参数:无 在主体代码中,两次调用printStr,使得在屏幕最上方以黑底绿字显示字符串,在屏幕最下方以黑底红色显示字符串 ; 实验代码:assume ds:data, cs:code data segment str db 'try' len equ $ - str data ends code segment start: mov ax,data mov ds,ax mov ax,0b800h mov es,ax mov bh,0 mov bl,2 call printStr mov bh,24 mov bl,4 call printStr mov ax,4c00h int 21h printStr: mov si,offset str mov al,0a0h mul bh mov di,ax mov cx,len mov bh,bl s: mov bl,[si] mov es:[di],bx inc si add di,2 loop s ret code ends end start
运行结果:
Task5
在80×25彩色字符模式下,在屏幕最后一行正中间显示学号。要求输出窗口蓝底,学号和两侧折线,以白色前景色显示。 实验代码:assume ds:data, cs:code data segment stu_no db '201983290408' len = $ - stu_no data ends code segment start: mov ax, data mov ds, ax mov ax, 0b800h mov es, ax call backgroundCol mov di, 3840 call printLine mov di, 3908 mov si, offset stu_no call printStu_no mov ax, 4c00h int 21h backgroundCol: mov ax,1700h mov di, 0 mov cx, 4000 s: mov es:[di], al mov es:[di+1], ah add di, 2 loop s ret printLine: mov cx, 50h mov ax, 172dh s1: mov es:[di], al mov es:[di+1], ah add di,2 loop s1 ret printStu_no: mov cx, len mov ah, 17h s2: mov al, [si] mov es:[di], al mov es:[di+1], ah inc si add di, 2 loop s2 ret code ends end start
运行结果:
四、实验总结
通过本次实验,我理解和掌握了转移指令的跳转原理,掌握使用call和ret指令实现子程序的方法,理解和掌握其参数传递方式,理解和掌握80×25彩色字符模式显示原理; 综合应用寻址方式和汇编指令完成简单应用编程。