airklo

实验任务1

(1)验证性实验:有些汇编指令会影响到标志寄存器中的一个或多个状态标志位。 在debug环境中,分别实践、观察:

① add指令对标志寄存器中的零标志位ZF(Zero Flag)、进位标志位CF(Carry Flag)是否有影响?

② inc指令对标志寄存器中的零标志位ZF(Zero Flag)、进位标志位CF(Carry Flag)是否有影响?

 

在debug环境中输入如上指令,发现add指令对零标志位和进位标志位都有影响。

 

 

 在debug中输入如上指令,发现inc指令对零标志位有影响,但是对进位标志位没有影响。

(2)使用任意文本编辑器,录入8086汇编源码task1.asm。

 1 assume cs:code, ds:data
 2 
 3 data segment
 4    x dw 1020h, 2240h, 9522h, 5060h, 3359h, 6652h, 2530h, 7031h
 5    y dw 3210h, 5510h, 6066h, 5121h, 8801h, 6210h, 7119h, 3912h
 6 data ends
 7 code segment 
 8 start:
 9     mov ax, data
10     mov ds, ax
11     mov si, offset x
12     mov di, offset y
13     call add128
14 
15     mov ah, 4ch
16     int 21h
17 
18 add128:
19     push ax
20     push cx
21     push si
22     push di
23 
24     sub ax, ax
25 
26     mov cx, 8
27 s:  mov ax, [si]
28     adc ax, [di]
29     mov [si], ax
30 
31     inc si
32     inc si
33     inc di
34     inc di
35     loop s
36 
37     pop di
38     pop si
39     pop cx
40     pop ax
41     ret
42 code ends
43 end start

对程序进行汇编、链接,得到可执行程序task1.exe。在debug中调试程序,并回答问题。

① line31~line34的4条inc指令,能否替换成如下代码?你的结论的依据/理由是什么?

1 add si, 2
2 add di, 2

② 在debug中调试,观察数据段中做128位加之前,和,加之后,数据段的值的变化。

查看数据段中的数据,进行add128后查看,发现结果如下

 把inc替换成add,结果和上图一样。

 

所以只对这组数据而言,将inc替换成add是可行的,因为add指令没有产生任何进位,所以不会对标志寄存器的进位寄存器的值产生影响,也就不会影响adc指令的结果。

但本质上是不可以替换的,inc和add对进位寄存器的影响不同,如果si或者di的值在本次计算中产生了进位,它会对adc指令产生影响。

 

实验任务二

 使用任意文本编辑器,录入8086汇编源码task2.asm。

 1 assume cs:code, ds:data
 2 data segment
 3 str db 80 dup(?)
 4 data ends
 5 code segment
 6 start:
 7 mov ax, data
 8 mov ds, ax
 9 mov si, 0
10 s1:
11 mov ah, 1
12 int 21h
13 mov [si], al
14 cmp al, \'#\'
15 je next
16 inc si
17 jmp s1
18 next:
19 mov ah, 2
20 mov dl, 0ah
21 int 21h
22 mov cx, si
23 mov si, 0
24 s2: mov ah, 2
25 mov dl, [si]
26 int 21h
27 inc si
28 loop s2
29 mov ah, 4ch
30 int 21h
31 code ends
32 end start

 对源程序task2.asm进行汇编、链接,得到可执行文件task2.exe。

运行程序,从键盘上输入一串字符,以#结束(比如,输入George Orwell, 1984#),观察结果。结合运 行结果,理解代码并回答问题:

运行结果如下,程序的目的是输出#之前输入的字符到屏幕上。

 

 

① 汇编指令代码line11-18,实现的功能是? 

通过键盘输入一个字符存储进al中,并将它存储到ds:[si]中,然后拿这个字符和#号进行比较,如果为#就跳转到next代码段,否则数据段偏移地址加一,回到开头继续存储键盘输入的字符。

② 汇编指令代码line20-22,实现的功能是?

输出一个换行到屏幕上。

③ 汇编指令代码line24-30,实现的功能是?

通过循环,将数据段中存储的从键盘中输入的字符输出到屏幕上,由于#作为跳转的条件并没有存入数据段中,所以#不会被输出。

 

实验任务三

针对8086CPU,已知逻辑段定义如下:

1 data segment
2 x dw 91, 792, 8536, 65521, 2021
3 len equ $ - x
4 data ends

编写8086汇编源程序task3.asm,在屏幕上以十进制形式输出data段中这一组连续的数据,数据和数据 之间以空格间隔。

代码:

 1 assume ds:data, cs:code
 2 
 3 data segment
 4     x dw 91, 792, 8536, 65521, 2021
 5     len equ $ - x
 6 data ends
 7 
 8 
 9 code segment
10 start:
11     mov cx,5
12     mov ax,data
13     mov ds,ax;ds作数据段
14     mov si,0
15     
16 s:        
17     mov dx,0;初始化处理dx作为高位为0
18     mov ax,ds:[si];初始化ax
19 
20     call printNumber;打印一个16位数
21     call printSpace;打印一个空格
22 
23     inc si
24     inc si;字数据占两个字节
25     loop s
26     
27     mov ax,4c00h
28     int 21h
29 
30 printNumber:
31     push cx;cx存的数之后也要用,先存起来
32     mov cx,0;cx用来计算出栈的数字个数
33 
34 s1:    
35     mov bx,10
36     div bx;除以10,余数在DX里,商在AX中
37     push dx;dx入栈
38     inc cx;入栈的数字加一
39     cmp ax,0;ax和0做比较
40     je next;商为0跳转到next
41 
42     mov dx,0
43     jmp s1
44 
45 next:    
46     pop bx;出栈存给bx,因为每次只有一个数,所以高位存0,低位存数字
47 
48     mov ah,2;调用中断2号子功能
49     mov dl,bl;只有低位存数字,只把bl给dl即可,bh里是0
50     add dl,30h;加30将数字转变成字符
51     int 21h
52     loop next;循环直到所有数字都已经输出
53 
54     pop cx
55     ret
56 
57 
58 printSpace:
59     mov ah,2
60     mov dl,\' \'
61     int 21h
62     ret
63 
64 code ends
65 end start

效果:

在debug环境中运行,发现已经将数字显示到屏幕上。

 

 

 

实验任务四

针对8086CPU,已知逻辑段定义如下:

1 data segment
2 str db "assembly language, it\'s not difficult but tedious"
3 len equ $ - str
4 data ends

编写8086汇编源程序task4.asm,将data段中字符串里的小写字符转换成大写。

要求: 编写子程序strupr

功能:将包含任意字符的字符串中的小写字母变成大写 入口参数 (ds:si ) 字符串首地址的段地址和偏移地址分别送至ds和si (cx) 字符串的长度

出口参数:无 在主体代码中,设置入口参数,调用strupr, 实现题目要求。

代码:

 1 assume cs:code,ds:data
 2 data segment
 3     str db "assembly language, it\'s not difficult but tedious"
 4     len equ $ - str
 5 data ends
 6 
 7 code segment
 8 start:
 9     mov ax,data
10     mov ds,ax;ds作为数据段
11     mov si,0
12     mov cx,len;记录循环次数
13     call strupr
14     mov ah, 4ch
15     int 21h
16 
17 strupr:
18     mov al,[si]
19     cmp al,\' \' ;和空格作比较
20     je s1;如果是空格就跳过and操作
21     cmp al, \',\' ;和逗号作比较
22     je s1;如果是逗号就跳过and操作
23     cmp al, 00100111B;和单引号比较
24     je s1;如果是单引号就跳过and操作
25     and al,0dfh
26 s1:
27     mov [si],al;反存入内存
28     inc si
29     loop strupr
30 
31     
32 code ends
33 end start

在debug环境中运行,查看运行前后的数据段内的信息,发现已经成功将数据变为大写

 

实验任务五

使用任意文本编辑器,录入8086汇编源码task5.asm。

对源程序task5.asm进行汇编、链接,得到可执行文件task5.exe。

运行程序,输入7,观察结果。输入其他字符,观察结果。结合运行结果和注释,理解代码实现的功能。

代码:

 1 assume cs:code, ds:data
 2 
 3 data segment
 4     str1 db "yes", \'$\'
 5     str2 db "no", \'$\'
 6 data ends
 7 
 8 code segment
 9 start:
10     mov ax, data
11     mov ds, ax
12 
13     mov ah, 1
14     int 21h
15 
16     mov ah, 2
17     mov bh, 0
18     mov dh, 24
19     mov dl, 70
20     int 10h
21 
22     cmp al, \'7\'
23     je s1
24     mov ah, 9
25     mov dx, offset str2
26     int 21h
27 
28     jmp over
29 
30 s1: mov ah, 9
31     mov dx, offset str1
32     int 21h
33 over:  
34     mov ah, 4ch
35     int 21h
36 code ends
37 end start

效果:

输入7:

不输入7:

 程序的功能:

从功能上来说,程序的功能是输入7会在屏幕上输出一个yes,输入7以外的字符会在屏幕上输出一个no

从代码上来说,程序首先接受键盘输入的字符,随后设置光标在屏幕上的位置(也就是字符串在屏幕上显示的位置)然后拿这个字符和字符‘7’进行比较,如果比较成功就会跳入s1函数在屏幕上输出str1也就是yes。如果比较不成功就会顺序执行在屏幕上输出str2的字符串也就是no。

 

实验任务六

实验任务1、2、3、5中使用了不少系统提供的中断例程。

本实验任务中,要求自行实现一个42号软中断 例程,使得通过 int 42 或 int 2ah 软中断调用,实现在屏幕最下方中间以黑底绿字打印"welcome to 2049!"。

代码:

 1 assume cs:code
 2 
 3 code segment
 4 start:
 5     ; 42 interrupt routine install code
 6     mov ax, cs
 7     mov ds, ax
 8     mov si, offset int42  ; set ds:si
 9 
10     mov ax, 0
11     mov es, ax
12     mov di, 200h        ; set es:di
13 
14     mov cx, offset int42_end - offset int42
15     cld
16     rep movsb
17 
18     ; set IVT(Interrupt Vector Table)
19     mov ax, 0
20     mov es, ax
21     mov word ptr es:[42*4], 200h
22     mov word ptr es:[42*4+2], 0
23 
24     mov ah, 4ch
25     int 21h
26 
27 int42: 
28     jmp short int42_start
29     str db "welcome to 2049!"
30     len equ $ - str
31 
32     ; display string "welcome to 2049!"
33 int42_start:
34     mov ax, cs
35     mov ds, ax
36     mov si, 202h
37 
38     mov ax, 0b800h
39     mov es, ax
40     mov di, 24*160 + 32*2
41 
42     mov cx, len
43 s:  mov al, [si]
44     mov es:[di], al
45     mov byte ptr es:[di+1], 2
46     inc si
47     add di, 2
48     loop s
49 
50     iret
51 int42_end:
52    nop
53 code ends
54 end start
1 assume cs:code
2 code segment
3 start:
4 int 42 ; 调用自己实现的42号软中断
5 mov ah, 4ch
6 int 21h
7 code ends
8 end start

 

效果:

 

 通过此项实现任务,你对中断、软中断实现机制的理解

中断也就是硬中断,通过硬件来实现对进程的强制中断,它可以直接中断CPU的执行。

软终端通过当前执行的程序来实现中断,它不可以直接中断CPU的执行。

程序通过使用int指令来触发软中断。

 

实验总结:

通过本次实验,提高了对汇编语言标志寄存器和软中断的理解。其中第一题和第二题通过观察代码,增加对标志寄存器的理解。

第一题中,inc指令和add指令对零标志位都有影响,但是inc操作对进位标志位没有影响,再加上adc指令除了add后面的内存单元或立即数外,还会加上进位标志位的位数,但第一题里因为没有产生进位,所以看起来答案是一样的,但本质inc和add是不一样的。由此衍生出第一题的核心内容。

第二题的核心在于cmp al, \'#\'和 je next这两条指令,cmp是通过做没有存储结果的减法来对标志寄存器进行操作,je是通过判断标志寄存器中的数值来进行是否跳转的判断,这两条本质可以理解为高级语言中的if操作。

第三第四题是通过对上面两道题的理解,来进行自己的编程实现。第三题通过判断商是否为0作为跳转条件,以此实现位数不确定的数值的打印,这是对上一次实验内容的衍生。第四题比第三题相对容易,只是对内存单元进行操作,这里不再赘述。

另外在上面四题中,应用了中断的功能来实现在屏幕上打印内容或者输入内容,由此开启第五题和第六题的题目。第五题和第六题通过几个代码对系统自带的中断指令和自己写的中断指令进行结合理解,让还没有学习中断内容的我能够自我预习了解了一部分内容,提高了下次课程的效率。

分类:

技术点:

相关文章:

  • 2021-11-19
  • 2021-06-07
  • 2021-11-11
  • 2022-12-23
  • 2022-12-23
  • 2021-08-19
猜你喜欢
  • 2021-12-04
  • 2021-09-30
  • 2022-12-23
  • 2021-08-03
  • 2022-12-23
相关资源
相似解决方案