实验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
1.2运行结果:

 

 1.3回答问题

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

答案:跳转的位移量:由跳转指令E2F2可知,F2为补码,其原码对应的十进制数为-14,故位移量为-14。对于CPU来说,在执行loop指令时,当前IP地址为0019,加上该指令的字节数(2字节)后为001B,再加上位移量-14后跳转地址即为000D,即标号s1其后指令的偏移地址。

 2.line44,汇编指令 loop s2 跳转时,是根据位移量跳转的。通过debug反汇编,查看其机
器码,分析其跳转的位移量是多少?(位移量数值以十进制数值回答)从CPU的角度,说明
是如何计算得到跳转后标号s2其后指令的偏移地址的。
答案:由跳转指令E2F0可知,F0为补码,其原码对应的十进制数为-10,故位移量为-10。对于CPU来说,在执行loop指令时,当前IP地址为0037,加上该指令的字节数(2字节)后为001B,再加上位移量-10后跳转地址即为0029,即标号s2其后指令的偏移地址。
3.反汇编截图:

 

 

 

 

 
2. 实验任务2
录入8086汇编程序源码task2.asm。
task2.asm
assume cs:code, ds:data
data segment
dw 200h, 0h, 230h, 0h
data ends
stack segment
db 16 dup(0)
stack ends
code segment
start:
mov ax, data
mov ds, ax
mov word ptr ds:[0], offset s1
mov word ptr ds:[2], offset s2
mov ds:[4], cs
mov ax, stack
mov ss, ax
mov sp, 16
call word ptr ds:[0]
s1: pop ax
call dword ptr ds:[2]
s2: pop bx
pop cx
mov ah, 4ch
int 21h
code ends
end start

问题:

① 根据call指令的跳转原理,先从理论上分析,程序执行到退出(line31)之前,寄存器(ax) = ? 寄存器
(bx) = ? 寄存器(cx) = ?
1.ax=0021 bx=0026 cx=076c
② 对源程序进行汇编、链接,得到可执行程序task2.exe。使用debug调试,观察、验证调试结果与理论
分析结果是否一致。

2实验结果如图,call word ptr ds:[0] 将下一条指令的ip0021压入栈之后 pop ax后ax中的结果应该为0021

call dword ptr ds:[2] 指令将下一条指令的cs:ip压入栈,然后将ip 和cs依次出栈到bx,cx中,故bx-0026 cx=076c

 

 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, 实现题目要求。
测试结果:

 

 int 21h中的2号子功能说明如下: 

mov  ah, 2
mov  dl, ××   ; ××是待输出的字符,或其ASCⅡ码值
int 21h
编写后的代码:
assume cs:code, ds:data

data segment
x db 99, 72, 85, 63, 89, 97, 55
len equ $- x
data ends

code segment
start:
  mov ax, data
  mov ds, ax;
  mov si, 0
  mov cx, len ;数据为byte,len即为数据长度
  s:
   mov ah, 0 ;数字只有一个字节所以ah=0
   mov al, [si]
   mov bx, offset printNumber
   call bx
   mov bx, offset printSpace
   call bx
   inc si
   loop s
  mov ah, 4ch
  int 21h

  printNumber:
    mov bl, 10
    div bl;分离十位和个位
    mov bx, ax

    mov dl, bl ;取商
    add dl, 30h ;转换成ascii
    mov ah, 2 ;调用int 21h的二号子程序
    int 21h;

    mov dl, bh ;取余数
    add dl, 30h ;转换成ascii
    mov ah, 2 ;调用int 21h的二号子程序
    int 21h;
  ret

  printSpace:
    mov dl, ' '
    mov ah, 2
    int 21h
  ret

code ends
end start
结果截图:

 

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,使得在屏幕最上方以黑底绿字显示字符串,在屏幕最下方以黑
底红色显示字符串
正确编写后,预期测试结果如下:

 

 源码:

assume cs:code, ds:data

data segment 
    str db 'try' 
    len equ $ - str 
data ends

code segment
start:
    mov ax, data
    mov ds, ax
    
    mov bl, 2
    mov bh, 0
    call printStr

    mov bl, 4    
    mov bh, 24
    call printStr

    mov ah, 4ch
    int 21h    

printStr:
    mov ax, 0b800h
    mov es, ax

    mov si, offset str
    mov cx, len  

    mov ax, 00a0h
    mul bh
    mov di, ax

s:  mov al, [si]
    mov es:[di], al
    mov es:[di+1], bl
    inc si
    add di, 2
    loop s    
    ret

code ends
end start

5.实验任务:
针对8086CPU,针对8086CPU,已知逻辑段定义如下:
data segment
stu_no db '20498329042'
len = $ - stu_no
data ends 
在80×25彩色字符模式下,在屏幕最后一行正中间显示学号。要求输出窗口蓝底,学号和两侧折线,以
白色前景色显示。
源码:
assume cs:code, ds:data

data segment 
    stu_no db '201983290351'
    len = $ - stu_no
data ends

code segment
start:
    mov ax, data
    mov ds, ax
     
    mov ax, 0b800h    
    mov es, ax
    mov al, 24
    mov dl, 80
    mul dl
    mov cx, ax
    mov di, 0

s1:mov al, 17h           ;除最后一行页面设置蓝色
    mov es:[di], byte ptr 20h
    mov es:[di+1], al
    add di, 2
    loop s1
    
    mov ax, 00a0h
    mov bh, 24
    mul bh
    mov di, ax
    call printStr
    
    mov si, offset stu_no
    mov cx, len
    call printNum
    
    call printStr

    mov ah, 4ch
    int 21h

printStr:
    mov ax, 80
    sub ax, len
    mov bl, 2
    div bl
    mov ch, 0
    mov cl, al

s2:mov ah, 17h
    mov al, '-'
    mov es:[di], ax
    add di, 2
    loop s2
    ret
   
printNum:
s3:mov ah, 17h
    mov al, [si]
    mov es:[di], ax
    inc si
    add di, 2
    loop s3
    ret

code ends
end start
实验结果:

 

 

posted @ 2021-12-07 12:31  网工唐豪  阅读(28)  评论(1)    收藏  举报