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

四、实验结论

1、实验任务1

实验源码

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

运行截图

 

 

 问题一:反汇编截图如下:

 

 

  可以看到, loop s1 反汇编之后是 loop 000D 即是跳转的地址为000D,跳转是根据位移量跳转的,跳转规则为 当前IP+偏移量=跳转地址 ,当前IP为001B,转换成十进制是27,跳转地址是000D,转换成十进制是13,可以计算的到偏移量是 -14 。

  从CPU角度,可以查看存储的内容,可以发现存储的内容是 F2 ,

转换成二进制为 1111 0010 ,而 -14 的补码为 1110 0010 ,刚好就是F2,所以CPU是把偏移量存储下来,再根据IP的值来计算偏移之后的指令地址的。

问题二:反汇编截图如下:

 

 

  可以看到, loop s2 反汇编之后是 loop 0029 即是跳转的地址为0029,跳转是根据位移量跳转的,跳转规则为 当前IP+偏移量=跳转地址 ,当前IP为0039,转换成十进制是57,跳转地址是0029,转换成十进制是41,可以计算的到偏移量是  -16 。

  从CPU角度,可以查看存储的内容,可以发现存储的内容是 F0 ,

转换成二进制是 1111 0000 ,而 -16 的补码为 1111 0000 ,刚好就是F0,所以CPU是把偏移量存储下来,再根据IP的值来计算偏移之后的指令地址的。

 问题三:反汇编截图已经给出

2、实验任务2

程序源码

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

调试、反汇编截图:

 

(1)理论分析,在程序退出之前,ax=21,bx=26,cx=076c。

(2)debug调试,验证,结果为

 

 与理论分析结果一致

3、实验任务3

程序源码

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, offset x
    mov cx, len
    
s:    mov ah, 0
    mov al, [si]
    call printNumber
    call printSpace
    
    inc si
    loop s
    
    mov ah, 4ch
    int 21h
    
printNumber:    
    mov bx, 10
    div bl
    mov bx, ax
    add bx, 3030h
    mov ah, 2
    mov dl, bl
    int 21h
    mov ah, 2
    mov dl, bh
    int 21h
    ret

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

    
code ends
end start

运行测试截图

 

 与预期要求一致

4、实验任务4

程序源码

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 si, offset str
    mov cx, len
    
    mov bl, 0ah
    mov bh, 0
    call printStr
    
    mov cx, len
    mov si, offset str
    mov bl, 0ch
    mov bh, 24
    call printStr
    
    mov ah, 4ch
    int 21h
    


printStr:
    mov al, 00a0h
    mul bh
    mov di, ax
    mov ax, 0b800h
    mov es, ax
    
    mov al, bl
    
s:    mov ah, ds:[si]
    mov es:[di], ah;
    mov es:[di+1], bl;
    add di, 2
    inc si
    loop s
    ret
    
    
code ends
end start

运行测试截图

 

 实验结果符合预期

5、实验任务5

程序源码

assume cs:code, ds:data

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

code segment
start:
    mov ax, data
    mov ds, ax
    mov si, offset stu_no
    mov cx, len

    mov ax, 0b800h
    mov es, ax
    mov di, 0
    
    mov al,24
    mov dl, 80
    mul dl
    mov cx, ax
s:    
    mov al, 17h
    mov es:[di], byte ptr 20h
    mov es:[di+1], al
    add di, 2
    loop s

    mov ax, 80
    sub ax, len
    mov dl, 2
    div dl
    mov cx, 0
    mov cl, al
    mov bx, cx
    call gang
    mov cx, len
s2:
    mov al, ds:[si]
    mov ah, 17h
    mov es:[di], ax
    add di, 2
    inc si
    loop s2
    mov cx, bx
    call gang
    mov ah, 4ch
    int 21h
    
    
gang:
    
s1:    mov al, '-'
    mov ah, 17h
    mov es:[di], ax
    add di, 2
    loop s1
    ret
code ends
end start

运行测试截图

 

 实验结果与预期一致。

五、实验总结

  通过本次实验,我掌握了跳转指令的使用、子程序的编写以及显示字符的方法,使用call指令与ret指令配合实现子程序的编写,窗口显示的有25行,80列。

posted @ 2021-11-28 12:56  博客123456789  阅读(172)  评论(3编辑  收藏  举报