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

实验结论

1.实验任务1

代码截图:

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

 

 对其进行汇编链接之后,使用debug进行调试

使用u指令反汇编:

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

 

 可见loop要跳转到的地址为13,s1偏移量的计算方法是s1上一条指令的偏移地址加上上一条指令的长度,上一条指令的便宜地址为11,而上一条指令B402的长度为2字节,所以计算出s1的偏移量为:11+2=13

然后我们运行至第一个loop之后,再进行一次反汇编:

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

 

 这次s2的计算方法和上面的一致,上一条指令的偏移地址为39,而B402的长度为2字节,所以s2的偏移地址为39+2=41

2.实验任务2

源代码截图:

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

 

 理论分析:

首先,第16~18行,将s1的偏移地址存入到了data段偏移量为0,1的两个字节中,将s2的偏移地址存入到了偏移量为2,3的两个字节中,将code段地址存到了偏移量为4,5的两个字节中

然后在第24行使用了call指令,call指令后的指令偏移量,也就是s1的偏移量入栈,并且跳转执行s1的代码,将栈顶字节出栈并赋给ax,ax也就是s1标记地址的偏移量

然后在第27行第二次使用call指令,call指令之后的参数为一个双字节指针,所以当前代码段的段地址cs和下一条指令的偏移地址也就是s2的偏移地址相继入栈,然后跳转执行s2的代码,先后将栈顶出栈并赋给了bx和cx,所以bx为s2标记地址的偏移量,cx为当前代码段也就是cs的段地址

运行并求证:

汇编链接代码,并使用debug调试:

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

 

 运行到第一次call之后,可见确实执行了s1后的代码,ax的值也确实是s1所标记地址的偏移量

我们继续向下执行:

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

 

 执行到第二次call,并运行两次pop之后,可见第二次call之后确实执行了s2之后的代码,并且bx的值确实是s2标记地址的偏移量,cx确实是当前代码段地址也就是cs寄存器中的内容

3.实验任务3

 实验代码:

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

 

 

 运行结果:

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

 

 

4.实验任务4

代码:

 1 assume cs:code, ds:data
 2 
 3 data segment 
 4     str db 'try' 
 5     len equ $ - str
 6 data ends
 7 
 8 code segment
 9 start:
10     mov ax, data
11     mov ds, ax 
12     mov si, 0 
13     mov cx, 3
14     mov bl, 02h 
15     mov bh, 10 
16     call printStr 
17     mov ah, 4ch 
18     int 21h 
19 printStr:
20     mov ax, 0b800h
21     mov es, ax 
22     mov ax, 0a0h 
23     mul bh 
24     mov bp, ax 
25     mov dx, 0
26 s:
27     mov al, ds:[si] 
28     mov ah, bl 
29     mov es:[bp], ax 
30     inc si 
31     add bp, 2
32     loop s 
33     ret
34 code ends 
35 end start 

运行结果:

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

 5.实验任务5

源代码:

assume cs:code, ds:data 

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

code segment 
start:
    mov ax, data 
    mov ds, ax 
    mov bp, 0 
    mov ax, 0b800h
    mov es, ax 
    mov bx, 1
    mov cx, 2080
s1:
    mov ah, 17h
    mov es:[bx], ah
    add bx, 2 
    loop s1
    mov bx, 3840
    call printMinus 
    mov cx, 12 
    call printStr
    call printMinus
    mov ax, 4c00h 
    int 21h 
printMinus:
    mov cx, 34
s2:
    mov al, '-'
    mov es:[bx], al
    add bx, 2
    loop s2 
    ret 
printStr:
    mov bp, 0 
s3:
    mov al, ds:[bp]
    mov es:[bx], al
    add bx, 2
    add bp, 1
    loop s3 
    ret 
code ends 
end start

运行结果:

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

 

 实验总结

这次的实验主要锻炼了我运行call和ret指令进行代码块封装和重用的能力,运用标记和ret可以封装一部分代码,并且可以通过call指令调用这段代码,这样就可以避免代码的重复冗余,节省了代码编写的时间。此外,我还学习到了很多在dos命令行上显示字符的知识,能够在命令行的任意位置以任何颜色显示想要显示的字符。

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


下一篇:phpcms模板标签整理