一、实验目的
1. 理解标志寄存器用途,理解常用标志位CF, ZF, OF, SF, TF, IF的用途和意义。 2. 理解条件转移指令je, jz, ja, jb, jg, jl等的跳转原理,掌握组合使用汇编指令cmp和条件转移指令实现分支和循环的用法 3. 了解软中断指令的用法,体验和理解中断原理 4. 综合应用寻址方式和汇编指令完成简单应用编程 二、实验准备 复习教材「第10章 call和ret指令」、「第11章 标志寄存器」 学习教材「第12章 内中断 」、「第13章 int指令」 三、实验内容 1. 实验任务1 使用任意文本编辑器,录入8086汇编源码task1.asm。assume cs:code, ds:data data segment x dw 1020h, 2240h, 9522h, 5060h, 3359h, 6652h, 2530h, 7031h y dw 3210h, 5510h, 6066h, 5121h, 8801h, 6210h, 7119h, 3912h data ends code segment start: mov ax, data mov ds, ax mov si, offset x mov di, offset y call add128 mov ah, 4ch int 21h add128: push ax push cx push si push di sub ax, ax mov cx, 8 s: mov ax, [si] adc ax, [di] mov [si], ax add si,2 add di,2 loop s pop di pop si pop cx pop ax ret code ends end start
对程序进行汇编、链接,得到可执行程序task1.exe。在debug中调试程序,并回答问题。
① line31~line34的4条inc指令,能否替换成如下代码?你的结论的依据/理由是什么?add si, 2 add di, 2
不能,add会影响进位标志符CF,进而影响到128位加法的结果,而inc则不会改变CF的值;
改成add后结果:
本题无进位溢出,所以无影响;
2. 实验任务2 使用任意文本编辑器,录入8086汇编源码task2.asm。 task2.asm ② 在debug中调试,观察数据段中做128位加之前,和,加之后,数据段的值的变化。
assume cs:code, ds:data data segment str db 80 dup(?) data ends code segment start: mov ax, data mov ds, ax mov si, 0 s1: mov ah, 1 int 21h mov [si], al cmp al, '#' je next inc si jmp s1 next: mov ah, 2 mov dl, 0ah int 21h mov cx, si mov si, 0 s2: mov ah, 2 mov dl, [si] int 21h inc si loop s2 mov ah, 4ch int 21h code ends end start
对源程序task2.asm进行汇编、链接,得到可执行文件task2.exe。
运行程序,从键盘上输入一串字符,以#结束(比如,输入George Orwell, 1984#),观察结果。结合运行结果,理解代码并回答问题: 运行结果:
① 汇编指令代码line11-18,实现的功能是?
接收输入字符并保存到ds段中,直到输入字符为‘#’为止且不包含‘#’
② 汇编指令代码line20-22,实现的功能是?打印换行符
③ 汇编指令代码line24-30,实现的功能是?打印ds中的字符
3. 实验任务3
编写8086汇编源程序task3.asm,在屏幕上以十进制形式输出data段中这一组连续的数据,数据和数据之间以空格间隔。 要求: 编写子程序printNumber 功能:以十进制形式输出一个任意位数的整数(整数范围0 ~ 65535) 入口参数:寄存器ax(待输出的数据 --> ax) 出口参数:无 编写子程序printSpace 功能:打印一个空格 入口参数:无 出口参数:无 在主体代码中,综合应用寻址方式和循环,调用printNumber和printSpace, 实现题目要求。 实验代码:assume cs:code,ds:data,ss:stack data segment x dw 91, 792, 8536, 65521, 2021 len equ $ - x data ends stack segment dw 8 dup(0) stack ends code segment start: mov ax, data mov ds, ax mov si, offset x mov ax, stack mov ss, ax mov sp, 16 mov cx, len/2 mov bx, 10 s: mov ax, word ptr ds:[si] push cx call printNumber call printSpace add si,2 pop cx loop s mov ax, 4c00h int 21h printNumber: mov cx, 0 s1: mov dx, 0 div bx push dx inc cx or ax,0 ;判断商位0 jnz s1 ;为0继续,不为0循环 s2: pop dx add dl, 30h mov ah, 2 int 21h loop s2 ret printSpace: mov ah, 2 mov dl, ' ' int 21h ret code ends end start
4. 实验任务4
assume cs:code,ds:data data segment str db "assembly language, it's not difficult but tedious" len equ $ - str data ends stack segment db 8 dup(0) stack ends code segment start: mov ax, data mov ds, ax mov si, 0 call strupr mov ax, 4c00h int 21h strupr: mov cx, len s: mov al, ds:[si] cmp al, 97 ;'a'之前 jl next cmp al, 122 ;'z'之后 jg next and al, 0dfh mov ds:[si], al next: inc si loop s ret code ends end start
5. 实验任务5
使用任意文本编辑器,录入8086汇编源码task5.asm。 task5.asmassume cs:code, ds:data data segment str1 db "yes", '$' str2 db "no", '$' data ends code segment start: mov ax, data mov ds, ax mov ah, 1 int 21h ;单字符输入 mov ah, 2 mov bh, 0 mov dh, 24 mov dl, 70 int 10h ;设置输出位置 cmp al, '7' je s1 ;对比判断 mov ah, 9 mov dx, offset str2 ;不同输出 int 21h jmp over s1: mov ah, 9 mov dx, offset str1 ;相同输出 int 21h over: mov ah, 4ch int 21h code ends end start
对源程序task5.asm进行汇编、链接,得到可执行文件task5.exe。
运行程序,输入7,观察结果。输入其他字符,观察结果。结合运行结果和注释,理解代码实现的功能。 实验结果:
输入7,右下角输出yes
输入其他字符,右下角输出no
6. 实验任务6 实验任务1、2、3、5中使用了不少系统提供的中断例程。本实验任务中,要求自行实现一个42号软中断例程,使得通过 int 42 或 int 2ah 软中断调用,实现在屏幕最下方中间以黑底绿字打印"welcome to2049!"。 建议配合教材第12章学习理解并实践。 task6_1.asm
assume cs:code code segment start: ; 42 interrupt routine install code mov ax, cs mov ds, ax mov si, offset int42 ; set ds:si mov ax, 0 mov es, ax mov di, 200h ; set es:di mov cx, offset int42_end - offset int42 cld rep movsb ; set IVT(Interrupt Vector Table) mov ax, 0 mov es, ax mov word ptr es:[42*4], 200h mov word ptr es:[42*4+2], 0 mov ah, 4ch int 21h int42: jmp short int42_start str db "welcome to 2049!" len equ $ - str ; display string "welcome to 2049!" int42_start: mov ax, cs mov ds, ax mov si, 202h mov ax, 0b800h mov es, ax mov di, 24*160 + 32*2 mov cx, len s: mov al, [si] mov es:[di], al mov byte ptr es:[di+1], 2 inc si add di, 2 loop s iret int42_end: nop code ends end start
task6_2.asm
assume cs:code code segment start: int 42 mov ah, 4ch int 21h code ends end start
对汇编源程序task6_1.asm进行汇编、链接,得到可执行程序task6_1.exe。运行task6_1.exe,实现将42号中断处理程序安装到0:200开始的连续内存空间,并设置中断向量表,使得将来通过 int 42 ,系统可以跳转到中断处理程序。
对汇编源程序task6_2.asm进行汇编、链接,得到可执行程序task6_2.exe。运行task6_2.exe。 运行结果: