任务一

验证性实验:有些汇编指令会影响到标志寄存器中的一个或多个状态标志位。

在debug环境中,分别实践、观察:

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

 有影响,ff 加上1后得到100h,最高有效位产生进位,al中的值为0,因此ZF结果为1,CF结果为1

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

对ZF有影响,对CF没有影响,得到的结果al为0,ZF值为1,而intel硬性规定inc指令不影响CF标志位

录入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 
 8 code segment
 9 start:
10     mov ax, data
11     mov ds, ax
12     mov si, offset x
13     mov di, offset y
14     call add128
15     
16     mov ah, 4ch
17     int 21h
18     
19 add128:
20     push ax
21     push cx
22     push si
23     push di
24     sub ax, ax
25     mov cx, 8
26 s:  mov ax, [si]
27     adc ax, [di]
28     mov [si], ax
29     
30     inc si
31     inc si
32     inc di
33     inc di
34     
35     loop s
36     pop di
37     pop si
38     pop cx
39     pop ax
40     ret
41 code ends
42 end start

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

1 add si, 2
2 add di, 2

可以替换,line31~line34指令的作用是寻找下一字节数据,一共8个字的数据不会涉及到进位对CF造成影响,所以也不会影响adc的计算,两者效果相同,如图所示:

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

加之前的数据段:

 加之后的数据段:

 

 

 

任务二

录入8086汇编源码task2.asm

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

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

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

读取键盘输入,加入到数据段当中。如果不是'#',继续读取,是'#'字符跳转到next标号处

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

显示输出数据 ah,该ascii码对应字符为换行符

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

显示输出数据段当中的字符数据

 

 

任务三

已知逻辑段定义如下:

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

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

 1 data segment
 2     x dw 91, 792, 8536, 65521, 2021
 3     len equ $ - x
 4 data ends
 5 
 6 ;使用32位除16位,否则数据太大
 7 code segment
 8 start:
 9     mov ax,data
10     mov ds,ax
11     mov ax,ds:[6]
12     mov dx,offset printNumber
13     mov cx,5
14     mov si,0
15 s0:    push cx
16     call printNumber
17     call printSpace
18     pop cx
19     loop s0
20     
21     mov ax,4c00h
22     int 21h
23     
24 printNumber:
25 s1:    mov ax,[si]
26     mov cx,0        ;记录余数个数
27 s2:    mov dx,0        ;循环获取余数
28     mov bx,10
29     div bx
30     or dx,30h
31     push dx
32     inc cx
33     mov dx,0
34     cmp ax,0
35     jz s3            ;等于零输出空格,不等于零继续获取
36     jnz s2
37     
38 s3:    mov ax,200h        ;完成取余循环之后,执行系统功能,输出dl
39     pop dx
40     int 21h
41     loop s3
42     
43     add si,2
44     ret                ;输出空格
45     
46 printSpace:
47     mov ax,200h
48     mov dl,' '
49     int 21h
50     ret
51 
52 code ends
53 end start

 

 

 

任务四

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

1 DATAS SEGMENT
2     str db "assembly language, it's not difficult but tedious"
3     len equ $ - str  
4 DATAS ENDS

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

 1 assume cs:code, ds:data
 2 
 3 data segment
 4     str_d db "assembly language, it's not difficult but tedious"
 5     len equ $ - str_d 
 6 data ends
 7 
 8 code segment
 9 start:
10     mov ax,data
11     mov ds,ax
12     mov cx,len
13     mov si,0
14 s:  call strupr
15     inc si
16     loop s
17     mov ah,4ch
18     int 21h
19     
20 strupr:
21     mov dl,[si]
22     cmp dl,61h        ;小于a跳过
23     jb s1
24     cmp dl,7ah        ;大于z跳过
25     ja s1
26     and dl,0dfh
27     mov [si],dl
28 s1:    ret
29     
30 code ends
31 end start

 

 

 

 

 

 

任务五

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

 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 ; 设置光标位置在第24行
19     mov dl, 70 ; 设置光标位置在第70列
20     int 10h ; 设置光标位置
21     
22     cmp al, '7'
23     je s1
24     mov ah, 9
25     mov dx, offset str2
26     int 21h ; 显示标号str2处的字符串
27     
28     jmp over
29     
30 s1: mov ah, 9
31     mov dx, offset str1
32     int 21h ; 显示标号str2处的字符串
33 over:
34     mov ah, 4ch
35     int 21h
36 code ends
37 end start

这段程序的功能是判断输入字符是不是7,如果是7,输出'yes',是其他字符则输出'no'

 

 

任务六

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

task6_1.asm

 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     mov ax, 0b800h
38     mov es, ax
39     mov di, 24*160 + 32*2
40     mov cx, len
41 s:     mov al, [si]
42     mov es:[di], al
43     mov byte ptr es:[di+1], 2
44     inc si
45     add di, 2
46     loop s
47     
48     iret
49 int42_end:
50     nop
51 code ends
52 end start
View Code

task6_2.asm

 1 assume cs:code
 2 
 3 code segment
 4 start:
 5     int 42 ; 调用自己实现的42号软中断
 6     
 7     mov ah, 4ch
 8     int 21h
 9 code ends
10 end start

 task6_1代码将中断处理程序存入到内存当中,程序入口地址从中断类型码N*4开始,段地址为N*4+2,偏移地址为N*4,并将42号表项写入到中断向量表中,实现当遇到中断类型码为42时,调用相应的中断处理程序,输出welcome to 2049!到相应位置。

 

 

总结

一些根据标志位跳转的指令

JZ  ;为0则跳转

JNZ  ;不为0跳转

JA  ;无符号大于跳转

JB  ;无符号小于跳转

JC  ;进位跳转

 

posted on 2021-12-15 22:15  toughm  阅读(185)  评论(2编辑  收藏  举报