ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2021-11-28 19:33:45  阅读:116  来源: 互联网

标签:di IP 编程 mov al 指令 call 跳转 ax


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

实验任务1

问题1.1

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

    image-20211128191659896

    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处。

    image-20211128191608233

    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进行测试:

image-20211128113813208

发现猜想正确。

实验任务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

效果

image-20211128180207536

实验任务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

效果

image-20211128175956002

加强

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

image-20211128180448641

实验任务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

效果

image-20211128185512374

总结

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

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

标签:di,IP,编程,mov,al,指令,call,跳转,ax
来源: https://www.cnblogs.com/Lihewin/p/15616277.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有