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

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

实验任务1

问题1.1

  • 对程序进行反汇编,运行至loop s1处。

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

    loop s1的机器码为E2F2。F2的八位二进制形式为11110010,补码为10001110,为-14。即位移量为14。

  • 从执行角度分析:

    1. CS:IP指向0771:0019 ,下一条loop指令机器码E2 F2。
    2. E2 F2进入指令缓冲器。
    3. 此时CX不为零,所以执行该指令。
    4. $IP = IP + 所读取到的指令的长度$ ==$IP + 2 = 001B$ ,CS:IP指向mov ah,2
    5. CPU执行缓冲器中指令
    6. 执行后IP = 000D,CS:IP指向mov dl,[si]

问题1.2

  • 运行至loop s2处。

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

    loop s2的机器码为E2F0。F2的八位二进制形式为11110000,补码为10010000,为-16。即位移量为16。

  • 与上题分析过程类似,略

实验任务2

问题2.1

call指令的跳转原理:

CPU 执行 call 指令时,进行两步操作:

  1. 将当前的 IP 或 CS 和 IP 压入栈中;
  2. 转移。

根据该原理进行分析:

  • ax 应当等于其上一条指令call word ptr ds:[0]所压入栈中的IP,为21
  • bx 应当等于其上一条指令call dword ptr ds:[2]所压入栈中的CS:IP中的IP,为26
  • cx 应当等于call dword ptr ds:[2]所压入栈中的CS:IP中的CS,具体数值未知

问题2.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 bl,byte ptr 10;这个除数10应该为8位的数据,故采用byte形式。
    mov si,offset x
    mov cx,len
    dec cx
    
s:	call printNumber
	call printSpace
	inc si
	loop s
	
	mov ax,4c00h
	int 21
	
printNumber:
	mov al,[si]
	mov ah,0h
	div bl;将al中的数除10,al中获得了商(实际上的十位数),ah中获得了余数(实际上的个位数)。
	mov dh,ah;ah在中断显示中必须为2,所以先把数据放在dh中。
	mov ah,2
	mov dl,al
	or dl,30h;将ascii转为ascii中对应的数字
	int 21h;显示十位数
	mov dl,dh
	or dl,30h
	int 21h;显示个位数
	ret
	
printSpace:
	mov ah,2
	mov dl,' '
	int 21h;输出一个空格
	ret
	
code ends
end start

效果

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

实验任务4

代码

assume cs:code, ds:data

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

code segment
start:
	mov ax,0b800h
	mov es,ax
	
    mov ax, data
    mov ds, ax
	mov si,offset x
	mov cx,len
	mov bl,00001010b
	mov bh,0;设定了首字符地址指向x,长度为len,颜色黑底绿字,指定第一行
	call printStr
	
	mov ax, data;直接初始化
    mov ds, ax
	mov si,offset x
	mov cx,len
	mov bl,00001100b
	mov bh,24;设定了首字符地址指向x,长度为len,颜色黑底红字,指定第25行
	call printStr;再次调用
	
	mov ax, 4c00h
	int 21h

printStr:
	mov al,160
	mul bh;在80*25显示模式中,屏幕上每行有160个字节,则将bh乘160即可让bh代表屏幕上第几行。
	mov di,ax
s:	mov al,[si]
	mov es:[di],al;ascii码
	mov es:[di+1],bl;这个字符的显示颜色
	inc si
	add di,2;转到两个字节后下一个显示字符的位置
	loop s
	ret
	
code ends
end start

效果

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

加强

如果将代码中 line 33 的 160 改为 1 ,则红色的 try 会显示在第一行的第 12(24/2)个字符位。

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

实验任务5

代码

assume cs:code, ds:data

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

code segment
start:
	mov ax,data
	mov ds,ax
	mov ax,0b800h
	mov es,ax
	call printBlueScreen;先画蓝屏底子
	mov di,0f00h;在最后一行的第一位开始画横线
	call printLines
	call printNum
	call printLines
	
	mov ax,4c00h
	int 21h
	
printBlueScreen:
	mov di,0h
	mov cx,007d0h;整个屏幕可以显示2000个字符,换算成八进制就是07d。	
	mov al,00010000b
s:	mov es:[di+1],al
	add di,2
	loop s
	ret

printLines:
	mov al,0002dh;横线的ascii码
	mov ah,00011111b
	mov cx,00022h;34次
s1:	mov es:[di],al
	mov es:[di+1],ah
	add di,2
	loop s1
	ret

printNum:
	mov cx,len
	mov si,offset stu_no
	mov ah,00011111b
s2:	mov al,[si]
	mov es:[di],al
	mov es:[di+1],ah
	inc si
	add di,2
	loop s2
	ret
	

code ends
end start

效果

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

总结

  • 本章实验主要复习了80*25显示模式以及常用的跳转命令。这些命令主要都是jmp命令的变体。

  • 在80*25彩色显示模式中,每个字符占两个字节,第一个字节为ascii码,第二个字节为该字符显示在屏幕上的颜色。

上一篇:为什么成为一名程序员?


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