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

实验结论

1. 实验任务1

使用任何一款文本编辑器,录入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

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

 

 s1标号处的地址是 000D ,即十进制的13;loop后面一条指令的地址是001B,即十进制27,相减得到-14,loop指令在对应的机器码中包含转移的位移而不是目的地址。其跳转位移量为s1到loop s1的地址差值。

 

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

 

跳转的位移量=0029 h- 0039 h=41-57=-16,loop指令在对应的机器码中包含转移的位移而不是目的地址。其跳转位移量为s2到loop s2的地址差值。

 

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

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

 

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

(ax)=pop ax的偏移地址;(bx)=pop bx的偏移地址,(cx)=段地址

 

3. 实验任务3

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

 data segment

  x db 99, 72, 85, 63, 89, 97, 55

  len equ $- x

data ends

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

要求: 编写子程序printNumber

功能:以十进制形式输出一个两位数

入口参数:寄存器ax(待输出的数据 --> ax)

出口参数:无

编写子程序printSpace

功能:打印一个空格

入口参数:无

出口参数:无

在主体代码中,综合应用寻址方式和循环,调用printNumber和printSpace, 实现题目要求。

 程序源码task3.asm

 1 assume cs:code, ds:data
 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 si,0
11 mov cx,len
12 
13 
14  s:
15     call printNumber
16     call printSpace
17 
18     inc si
19     loop s
20 
21 mov ax,4c00h
22 int 21h
23 
24  printNumber:
25  mov ah,0
26  mov al,ds:[0+si]
27  mov bl,10                  ;将两位数的十位和个位分别存储在两个内存单元中
28  div bl
29  mov ds:[len+si],al
30  mov ds:[len+1+si],ah
31 
32  mov ah,2                     ; 输出十位数字
33  mov dl,ds:[len+si]
34  add dl,30H
35   int 21h
36 
37 mov ah,2                     ; 输出个位数字
38 mov dl,ds:[len+1+si]
39 add dl,30h
40 int 21h
41 
42 ret
43 
44 
45 printSpace:
46 mov ah,2                      ;  输出空格
47 mov dl,20H
48 int 21h
49 
50 ret
51 
52 
53 code ends
54 end start

 运行测试截图:

 

 

4. 实验任务4

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

data segment

  str db 'try'

  len equ $ - str

data ends

编写8086汇编源程序task4.asm,在屏幕上以指定颜色、指定行,在屏幕上输出字符串。

要求:

编写子程序printStr

功能:在指定行、以指定颜色,在屏幕上显示字符串

入口参数

字符串首字符地址 --> ds:si(其中,字符串所在段的段地址—> ds, 字符串起始地址的偏 移地址—> si)

字符串长度 --> cx

字符串颜色 --> bl

指定行 --> bh (取值:0 ~24)

出口参数:无

在主体代码中,两次调用printStr,使得在屏幕最上方以黑底绿字显示字符串,在屏幕最下方以黑 底红色显示字符串

程序源码task4.asm

  1 assume cs:code
  2 data segment
  3     str db 'try',0                ;data段定义好要输出的字符串,以'0'作为结束标志
  4     len equ $ - str    
  5 data ends
  6 
  7 stack segment
  8     db 128 dup(0)
  9 code segment
 10 start:            mov ax,data
 11                 mov ds,ax
 12                 mov ax,stack
 13                 mov ss,ax
 14                 mov sp,128
 15                 call init_data                ;初始化数据
 16                 call printStr                ;显示的方法
 17                 call init_data2
 18                 call printStr
 19                 mov ax,4c00h
 20                 int 21h
 21 
 22 init_data2:        mov ax,0B800h
 23                 mov es,ax
 24                 mov dh,24    ;指定行号
 25                 mov dl,0        ;指定列号
 26                 mov cl,00000100B;指定颜色
 27                 mov si,0
 28                 mov di,0
 29                 ret
 30 
 31 init_data:        mov ax,0B800h
 32                 mov es,ax
 33                 mov dh,0    ;指定行号
 34                 mov dl,0        ;指定列号
 35                 mov cl,00000010B;指定颜色
 36                 mov si,0
 37                 mov di,0
 38                 ret
 39 
 40 printStr:        ;call clear_screen            ;清屏
 41                 call getRow                    ;获取指定行号的字节偏移数
 42                 call getCol                    ;获取指定列号
 43                 call show_String            ;真正的显示字符串方法
 44                 ret
 45 
 46 clear_screen:    push cx
 47                 push dx
 48                 push es
 49                 push bx
 50                 mov cx,2000     ;一页有2000字符,每个字符2个字节
 51                 mov dx,0700h    ;将屏幕上的双字用0700h代替
 52                 mov bx,0
 53 clearScreen:    mov es:[bx],dx
 54                 add bx,2
 55                 loop clearScreen
 56                 
 57                 pop bx
 58                 pop es
 59                 pop dx
 60                 pop cx
 61                 ret
 62 
 63 show_String:    push cx     ;保存下面将要用到的寄存器
 64                 push ds
 65                 push es
 66                 push dx
 67                 push si
 68                 push di
 69                 
 70                 mov dh,cl        ;高位存颜色
 71                 mov cx,0
 72 showString:        mov cl,ds:[si]
 73                 jcxz showStringRet
 74                 mov dl,ds:[si]    ;低位存字符
 75                 mov es:[di],dx
 76                 add di,2
 77                 inc si
 78                 jmp showString
 79                 
 80 showStringRet:    pop di        ;还原寄存器
 81                 pop si
 82                 pop dx
 83                 pop es
 84                 pop ds
 85                 pop cx
 86                 ret                
 87 
 88 getRow:            mov al,dh
 89                 mov bl,160   ;一行80字符,160字节
 90                 mul bl
 91                 mov di,ax
 92                 ret
 93 
 94 getCol:            mov al,dl
 95                 mov bl,2
 96                 mul bl
 97                 add di,ax
 98                 ret
 99                 
100 code ends
101 end start

运行测试截图

 

 

5. 实验任务5

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

data segment

  stu_no db '20498329042'

  len = $ - stu_no

data ends

在80×25彩色字符模式下,在屏幕最后一行正中间显示学号。要求输出窗口蓝底,学号和两侧折线,以 白色前景色显示。

程序源码task5.asm

  1 assume ds:data, cs:code
  2 data segment
  3        stu_no db '201983290195'
  4        ;db 2H,24H,71H          ;字符串属性值
  5        len = $ - stu_no
  6 data ends
  7 
  8 code segment
  9 start:  mov ax,data
 10         mov ds,ax            ;字符串及属性值所在段的段地址送入ds
 11 
 12         mov ax,0b800H
 13         mov es,ax            ;80×25彩色字符模式显示缓冲区段地址送入es
 14 
 15         ; 添加代码,通过循环逐个将每个字符及其属性送入相应的显示缓冲区对应行
 16         ; 即:将data段的字符及属性通过循环逐个mov到显示缓冲区(es)段相应的单元内
 17 
 18         ; 可以先尝试分别写三段代码,每次完成一行的显示
 19         ; 程序运行起来后,再尝试通过灵活的寻址方式和循环,对三段代码修改和简化
 20         ; 学习第10章子程序后,还可以进一步完善优化,设计子程序,将行号、列号、颜色属性设置成入口参数
 21          mov bx,0
 22          mov si,0
 23          mov cx,80
 24 
 25 s1:     ; mov ax,[bx]
 26         ; mov es:[bx+720h][si],ax
 27          mov al,23               ;存放颜色属性值蓝色
 28          mov es:[bx+1h][si],al
 29          inc bx
 30          inc si
 31          loop s1
 32 
 33 
 34          mov bx,0
 35          mov cx,80
 36          mov si,160
 37 
 38 s2:mov ax,[bx]
 39mov es:[bx+720h][si],ax
 40          mov al,23               ;存放颜色属性值蓝色
 41          mov es:[bx+1h][si],al
 42          inc bx
 43          inc si
 44          loop s2
 45 
 46 
 47          mov bx,0
 48          mov cx,80
 49          mov si,320
 50 
 51 s3:mov ax,[bx]
 52mov es:[bx+720h][si],ax
 53          mov al,23               ;存放颜色属性值蓝色
 54          mov es:[bx+1h][si],al
 55          inc bx
 56          inc si
 57          loop s3
 58 
 59          mov bx,0
 60          mov cx,1760
 61          mov si,480
 62 
 63 s4:mov ax,[bx]
 64mov es:[bx+720h][si],ax
 65          mov al,23               ;存放颜色属性值蓝色
 66          mov es:[bx+1h][si],al
 67          inc bx
 68          inc si
 69          loop s4
 70 
 71 
 72          mov bx,0
 73          mov cx,32
 74          mov si,3840
 75 
 76 s251:      mov ax,'-'
 77          mov es:[bx+0h][si],ax
 78          mov al,23               ;存放颜色属性值蓝色
 79          mov es:[bx+1h][si],al
 80          inc bx
 81          inc si
 82          loop s251
 83 
 84 
 85          mov bx,0
 86          mov cx,80
 87          mov si,3872
 88 
 89 s252:      mov ax,'-'
 90          mov es:[bx+0h][si],ax
 91          mov al,23               ;存放颜色属性值蓝色
 92          mov es:[bx+1h][si],al
 93          inc bx
 94          inc si
 95          loop s252
 96 
 97 
 98 
 99          mov bx,0
100          mov cx,len
101          mov si,2080
102 
103 s25:      mov ax,[bx]
104          mov es:[bx+720h][si],ax
105          mov al,23            ;白底蓝色
106          mov es:[bx+721h][si],al
107          inc bx
108          inc si
109          loop s25
110 
111          mov ax,4c00h
112          int 21h
113 code ends
114 end start

运行测试截图

 

posted on 2021-11-28 14:10  FlamingHotCheeto  阅读(42)  评论(2编辑  收藏  举报

导航