
文章目录
- 前言
- [1. 安装新的 int 9 中断例程](#1. 安装新的 int 9 中断例程)
-
- [1.1 任务及功能](#1.1 任务及功能)
- [1.2 分析问题](#1.2 分析问题)
-
- [1.2.1 改变屏幕的显示颜色](#1.2.1 改变屏幕的显示颜色)
- [1.2.2 其他键照常处理](#1.2.2 其他键照常处理)
- [1.2.3 原int 9中断例程入口地址的保存](#1.2.3 原int 9中断例程入口地址的保存)
- [1.2.4 新int 9中断例程的安装](#1.2.4 新int 9中断例程的安装)
- [1.3 得到完整的程序](#1.3 得到完整的程序)
- [2. 总结](#2. 总结)
- [3. 指令系统总结](#3. 指令系统总结)
-
- [3.1 数据传送指令](#3.1 数据传送指令)
- [3.2 算术运算指令](#3.2 算术运算指令)
- [3.3 逻辑指令](#3.3 逻辑指令)
- [3.4 转移指令](#3.4 转移指令)
- [3.5 处理机控制指令](#3.5 处理机控制指令)
- [3.6 串处理指令](#3.6 串处理指令)
- 结语
前言
📌
汇编语言是很多相关课程(如数据结构、操作系统、微机原理)的重要基础。但仅仅从课程的角度出发就太片面了,其实学习汇编语言可以深入理解计算机底层工作原理,提升代码效率,尤其在嵌入式系统和性能优化方面有重要作用。此外,它在逆向工程和安全领域不可或缺,帮助分析软件运行机制并增强漏洞修复能力。
本专栏的汇编语言学习章节主要是依据王爽老师的《汇编语言》来写的,和书中一样为了使学习的过程容易展开,我们采用以8086CPU为中央处理器的PC机来进行学习。
1. 安装新的 int 9 中断例程
下面,我们将安装一个新的int 9中断例程,使得原int 9中断例程的功能得到扩展。
1.1 任务及功能
任务:安装一个新的int 9中断例程
功能:在DOS下,按F1键后改变当前屏幕的显示颜色,其他的键照常处理。
1.2 分析问题
1.2.1 改变屏幕的显示颜色
怎么改变屏幕的颜色呢?
学习win 32 的朋友立马百度:有相应的函数吗?
其实,我们认真考虑下原理应该不难:改变从B800H开始的4000个字中的所有奇地址单元中的内容,当前屏幕的显示颜色即发生改变。
程序如下:
assembly
mov ax,0b800h
mov es,ax
mov bx,1
mov cx,2000
s: inc byte ptr es:[bx]
add bx,2
loop s
1.2.2 其他键照常处理
我们可以调用原int 9中断处理程序,来处理其他的键盘输入。
1.2.3 原int 9中断例程入口地址的保存
因为在编写的新int 9中断例程中要调用原int 9中断例程,所以,要保存原int 9中断例程的入口地址。
保存在哪里?
显然不能保存在安装程序中,因为安装程序返回后地址将丢失。
我们因此又将目标锁定在0:200单元处。
1.2.4 新int 9中断例程的安装
这个问题在前面己经详细讨论过。
我们可将新的int 9中断例程安装在0:204 处。
1.3 得到完整的程序
完整的程序如下:
assembly
assume cs:code
stack segment
db 128 dup (0)
stack ends
code segment
start:
mov ax,stack
mov ss,ax
mov sp,128
push cs
pop ds
mov ax,0
mov es,ax
mov si,offset int9 ;设置ds:si指向源地址
mov di,204h ;设置es:di指向目的地址
mov cx,offset int9end - offset int9 ;设置cx为传输长度
cld ;设置传输方向为正
rep movsb
push es:[9*4]
pop es:[200h]
push es:[9*4+2]
pop es:[202h]
cli
mov word ptr es:[9*4],204h
mov word ptr es:[9*4+2],0
sti
mov ax,4c00h
int 21h
int9:
push ax
push bx
push cx
push es
in al,60h
pushf
call dword ptr cs:[200h] ;当此中断例程执行时(CS)=0
cmp al,3bh ;F1的扫描码为3bh
jne int9ret
mov ax,0b800h
mov es,ax
mov bx,1
mov cx,2000
s:
inc byte ptr es:[bx]
add bx,2
loop s
int9ret:
pop es
pop cx
pop bx
pop ax
iret
int9end:
nop
code ends
end start
2. 总结
这一章中,我们通过对键盘输入的处理,讲解了CPU对外设输入的通常处理方法,即:
-
(1)外设的输入送入端口;
-
(2)向CPU 发出外中断(可屏蔽中断)信息;
-
(3)CPU检测到可屏蔽中断信息,如果IF=1,CPU在执行完当前指令后响应中断,执行相应的中断例程;
-
(4)可在中断例程中实现对外设输入的处理。
❗注意:端口 和中断机制,是CPU 进行I/O的基础。
3. 指令系统总结
我们对8086CPU 的指令系统进行一下总结。
大家若要详细了解8086 指令系统中的各个指令的用法 ,可以查看有关的指令手册。
8086CPU 提供以下几大类指令:
3.1 数据传送指令
比如:mov、push、pop、pushf、popf、xchg等都是数据传送指令,这些指令实现寄存器和内存、寄存器和寄存器之间的单个数据传送。
3.2 算术运算指令
比如:add、sub、adc、sbb、inc、dec、cmp、imul、idiv、aaa等都是算术运算指令,这些指令实现寄存器和内存中的数据的算数运算。
它们的执行结果影响标志寄存器的:sf、zf、of、cf、pf、af位。
3.3 逻辑指令
比如:and、or、not、xor、test、shl、shr、sal、sar、rol、ror、rcl、rcr 等都是逻辑指令。
除了not指令外,它们的执行结果都影响标志寄存器的相关标志位。
3.4 转移指令
可以修改IP ,或同时修改CS 和IP 的指令统称为转移指令。
转移指令分为以下几类:
-
(1)无条件转移指令,比如:jmp;
-
(2)条件转移指令,比如:jcxz、je、jb、ja、jnb、jna等;
-
(3)循环指令,比如:loop;
-
(4)过程,比如:call、ret、retf;
-
(5)中断,比如int、iret。
3.5 处理机控制指令
这些指令对标志寄存器或其他处理机状态进行设置,比如:cld、std、cli、sti、nop、clc、cmc、stc、hlt、wait、esc、lock等都是处理机控制指令。
3.6 串处理指令
这些指令对内存中的批量数据进行处理。
比如:movsb、movsw、cmps、scas、lods、stos等。
若要使用这些指令方便地进行批量数据的处理,则需要和rep、repe、repne等前缀指令配合使用。
结语
今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下。
也可以点点关注,避免以后找不到我哦!
Crossoads主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是作者前进的动力!
