实验3 转移指令跳转原理及其简单应用编程

四、实验结论

1. 实验任务1

此部分书写内容:

给出程序task1.asm源码,及运行截图

源码:

 1 assume cs:code, ds:data
 2 
 3 data segment
 4     x db 1, 9, 3
 5     len1 equ $ - x
 6 
 7     y dw 1, 9, 3
 8     len2 equ $ - y
 9 data ends
10 
11 code segment
12 start:
13     mov ax, data
14     mov ds, ax
15 
16     mov si, offset x
17     mov cx, len1
18     mov ah, 2
19  s1:mov dl, [si]
20     or dl, 30h
21     int 21h
22 
23     mov dl, ' '
24     int 21h
25 
26     inc si
27     loop s1
28 
29     mov ah, 2
30     mov dl, 0ah
31     int 21h
32 
33     mov si, offset y
34     mov cx, len2/2
35     mov ah, 2
36  s2:mov dx, [si]
37     or dl, 30h
38     int 21h
39 
40     mov dl, ' '
41     int 21h
42 
43     add si, 2
44     loop s2
45 
46     mov ah, 4ch
47     int 21h
48 code ends
49 end start

运行截图:

回答问题

① line27, 汇编指令 loop s1 跳转时,是根据位移量跳转的。通过debug反汇编,查看其机器码,分析其跳转的位移量是多少?(位移量数值以十进制数值回答)从CPU的角度,说明是如何计算得到跳转后标号s1其后指令的偏移地址的。

loop s1跳转到了000Dh的位置,即标号s1后面指令的偏移地址,跳转的位移量为:000Dh-001Bh=-14,用补码表示为F2。在执行loop指令时,CPU会算出需要跳转的位移量:标号处的地址-loop指令后的第一个字节的地址,然后与当前IP相加,求得所要跳转的偏移地址并赋值给IP,本实验即回到IP000Dh的位置。

回答问题

② line44,汇编指令 loop s2 跳转时,是根据位移量跳转的。通过debug反汇编,查看其机器码,分析其跳转的位移量是多少?(位移量数值以十进制数值回答)从CPU的角度,说明是如何计算得到跳转后标号s2其后指令的偏移地址的。

loop s2跳转到了0029h的位置,即标号s2后面指令的偏移地址,跳转的位移量为:0029h-0039h=-16,补码表示为F0。然后将偏移量与当前IP相加,求得所要跳转的偏移地址并赋值给IP,本实验即回到IP0029h的位置。

问题

③ 附上上述分析时,在debug中进行调试观察的反汇编截图

 

 

 

2. 实验任务2

此部分书写内容:

给出程序task2.asm源码

源码:

 

 1 assume cs:code, ds:data
 2 
 3 data segment
 4     dw 200h, 0h, 230h, 0h
 5 data ends
 6 
 7 stack segment
 8     db 16 dup(0)
 9 stack ends
10 
11 code segment
12 start:  
13     mov ax, data
14     mov ds, ax
15 
16     mov word ptr ds:[0], offset s1
17     mov word ptr ds:[2], offset s2
18     mov ds:[4], cs
19 
20     mov ax, stack
21     mov ss, ax
22     mov sp, 16
23 
24     call word ptr ds:[0]
25 s1: pop ax
26 
27     call dword ptr ds:[2]
28 s2: pop bx
29     pop cx
30 
31     mov ah, 4ch
32     int 21h
33 code ends
34 end start

 

给出分析、调试、验证后,寄存器(ax) = ? (bx) = ? (cx) = ? 附上调试结果界面截图。

① 根据call指令的跳转原理,先从理论上分析,程序执行到退出(line31)之前,寄存器(ax) =0021 寄存器(bx) =0026 寄存器(cx) =076C 

② 对源程序进行汇编、链接,得到可执行程序task2.exe。使用debug调试,观察、验证调试结果与理论分析结果是否一致。

g命令运行到pop cx的下一条指令处后,查看寄存器中内容,发现调试结果与理论分析结果一致。

可以验证,在执行call指令时,程序会跳转到指定的地址处执行,同时把call指令后面一条指令的ipcsip入栈。图中可见,执行call far [2]指令后,程序将076C0026依次入栈。

3. 实验任务3

此部分书写内容:

给出程序源码task3.asm 

 1 assume cs:code
 2 data segment 
 3     x db 99, 72, 85, 63, 89, 97, 55 
 4     len equ $- x 
 5 data ends
 6 code segment
 7 start:
 8     mov ax,data
 9     mov ds,ax
10     mov di,offset x
11     mov cx,len
12     s1:mov al,[di] ;将data段里的值赋值给ax
13        mov ah,0
14        call printNumber
15        call printSpace
16        inc di
17        loop s1
18     mov ah,4ch
19     int 21h
20 printNumber:mov bl,10
21         div bl 
22         mov si,ah ;把余数暂时存放在si中
23         mov ah,2
24         mov dl,al ;输出高位
25         or dl,30h
26         int 21h
27         mov dl,si ;输出低位
28         or dl,30h
29         int 21h
30         ret
31 
32 printSpace:mov ah,2
33        mov dl, ' '
34        int 21h
35        ret
36     
37 code ends
38 end start

运行测试截图

4. 实验任务4

此部分书写内容:

给出程序源码task4.asm 

源码:

 1 assume cs:code
 2 data segment
 3     str db 'try' 
 4     len equ $ - str 
 5 data ends
 6 
 7 code segment
 8 start:mov ax,data
 9       mov ds,ax
10       
11       mov si,offset str
12       mov cx,len
13       mov bl,2  ;绿字
14       mov bh,0  ;0行
15       call printStr
16 
17       mov si,offset str
18       mov cx,len
19       mov bl,4  ;红色
20       mov bh,24 ;24行
21       call printStr
22 
23       mov ah,4ch
24       int 21h
25 
26 printStr:mov ax,0b800h ;80x25彩色显示模式内存空间开始段地址
27          mov es,ax
28          mov al,160 ;计算显示空间偏移地址
29          mul bh ;与行号做乘法
30          mov di,ax ;将计算得出的偏移地址赋值给di
31          s:mov al,[si] ;数据属性写到低位
32            mov ah,bl ;颜色属性写到高位字节单元
33            mov es:[di],ax
34            add di,2
35            inc si
36            loop s
37          ret
38 
39 code ends
40 end start

运行测试截图

5. 实验任务5

此部分书写内容:

给出程序源码task5.asm 

源码:

 1 assume cs:code, ds:data
 2 data segment
 3         stu_no db '201983290491' 
 4     len = $ - stu_no
 5 data ends
 6 
 7 code segment
 8 start:mov ax,data
 9       mov ds,ax
10       mov ax,0b800h
11       mov es,ax
12       mov si,1
13       mov cx,1920 ;把0-23行都变成蓝底白字,24*80
14       mov bh,23 ;设置颜色属性
15       s1:mov es:[si],bh
16         add si,2
17     loop s1
18 
19       sub si,1 ;si-1,退回到24行0号位置
20       call cal
21       s2:mov es:[si],bx
22          add si,2
23      loop s2
24 
25 
26       mov cx,len ;打印学号
27       mov di,offset stu_no
28       s3:mov bl,[di]
29          mov es:[si],bx
30      add si,2
31      inc di
32      loop s3
33       
34       call cal ;再打印一次-
35       s4:mov es:[si],bx
36          add si,2
37      loop s4
38 
39 cal: mov ax,80 ;计算打印-(ascii码值为45)的个数
40      sub ax,len ;(80-学号长度)/2
41      mov dl,2
42      div dl
43      mov cl,al
44      mov ch,0
45      mov bl,45 ;给bl赋值-的ascii码值
46      ret
47 
48       mov ah, 4ch
49       int 21h
50 code ends
51 end start

运行测试截图

五、实验总结

1)loop指令的跳转方式:cpu会计算出当前跳转的位移量,并以补码形式保存,与IP相加,得出跳转地址。

2)80×25彩色字符模式:低位存放要显示数据的ascii码值,高位存放显示属性,在具体应用时,可以通过对指定地址的赋值,来实现显示指定数据的要求。

 

posted @ 2021-11-25 20:05  May==  阅读(7)  评论(0编辑  收藏  举报