编程语言
首页 > 编程语言> > 《x86汇编语言:从实模式到保护模式》笔记

《x86汇编语言:从实模式到保护模式》笔记

作者:互联网

x86汇编语言笔记

8086通用寄存器

16位寄存器:AX、BX、CX、DX、SI、DI、BP、SP。

前4个可分为高8位和低8位来使用:AH、AL、BH、BL、CH、CL、DH、DL。

内存分段

采用分段技术解决地址重定位问题,在硬件级别用两个段寄存器来支持,代码段寄存器CS和数据段寄存器DS。

实模式下CPU访问物理地址的方式:段基址:偏移地址

8086段寄存器

  • 代码段寄存器:CS
  • 数据段寄存器:DS
  • 附加段寄存器:ES
  • 栈段寄存器:SS

如何访问指令?

当程序开始时,CS指向代码段的起始地址,IP指令指针指向段内偏移。即CS:IP

注意:一般没有指定段寄存器时,默认使用DS。

如何访问数据?

在访问内存单元时,则采用DS:偏移地址

注意1:由于8086提供20位的物理地址,所以在计算物理地址时,要将段寄存器左移4位再加上偏移地址。由此可以得出8086最大只能访问1MB的内存空间。

注意2:内存是以字节为单位,内存中的每一个字节都对应一个物理地址。

计算机的启动流程

image-20220122202902641

注意:主引导扇区的最有两个字节是0x55和0xaa。

显存

显存存在于显卡之中,一般CPU是通过把显存映射到0xB8000~0xBFFFF这部分内存空间,来直接访问显存,显卡在加电自检后会初始化为80 * 25模式,即屏幕上显示25行,每行80个字符,每屏总共2000个字符。

显卡通过ASCII编码来识别CPU传入显存的数据。

屏幕上每个字符对应着显存中的连续两个字节,前一个字节为字符的ASCII代码,后一个字节为字符的显示属性。

image-20220122205323064

image-20220122205336604

image-20220122204330102

注意:Intel的处理器不允许把一个立即数传送到段寄存器,必须通过其他寄存器来中转。

mov指令

mov 目的操作数, 源操作数

注意:mov指令不允许目的操作数和源操作数都为内存单元,并且目的操作数不能为立即数。

注意:内存的增长是从低地址到高地址的。


除法

无符号除法指令:div


在段之间批量传送数据

使用movsb和movsw指令可以在两个段之间批量传送数据。movsb每次传送一个字节,movsw每次传送一个字。

格式:

; 重复执行
rep movsb ; rep指令前缀表示cx寄存器的值不为0,则重复执行该指令。
rep movsw
; 只执行一次
movsb
movsw

参数:

传送方向:


一个特殊的寄存器flag

通过cld指令来将flag寄存器的DF位设置为0,std指令将flag寄存器的DF位设置位1。

ZF位表示运算结果是否为0。

  • 1:运算结果为0
  • 0:运算结果不为0

DF位表示movsb/movsw指令是正向还是反向。

  • 0:正向
  • 1:反向

image-20220123204058429


关于使用寄存器提供偏移地址的问题

在8086处理器上只能使用BX、SI、DI、BP寄存器来提供偏移地址。


加一和减一、加法和减法

加一和减一对应的指令为incdec

加法和减法对应的指令为addsub


负数相关指令


jns指令

标志寄存器的SF位:当计算结果的最高位是0时,该位为0,否则为1。

jns指令,当标志寄存器的SF位为0时,则进行跳转。

标记寄存器的其他标志位

指令对标志寄存器的影响:

image-20220123215129845

条件跳转指令

根据标志跳转:

根据比较结果跳转:

可以通过cmp指令进行比较。

image-20220123215659834

image-20220123215722000

根据CX寄存器进行跳转:

jcxz:如果CX寄存器为0,则进行跳转。


栈段

由SS寄存器来确定段地址,SP寄存器确定偏移地址。

压栈:push指令,会将SP的内容减去操作数的字长,再把操作数压入栈中。

弹栈:pop指令,会将SP的内容加上操作数的字长,再把栈顶的数据弹出。

注意:实模式下,栈的大小为64KB。


寻址方式


I/O端口读写方式

I/O端口的范围:0 ~ 65535(0x0 ~ 0xffff)。

一些磁盘相关的知识:

image-20220124160018268


过程调用

call指令:

近调用的原理是先把IP寄存器的值压入栈中,再修改IP寄存器,而远调用则是分别把CS和IP寄存器的值压入栈,再修改CS和IP寄存器的值。

返回指令:

ret的原理是弹出栈中的值到IP寄存器,retf的原理是先弹出到IP寄存器,再弹到CS寄存器。


abc、shr、ror指令

image-20220124172321064


无条件跳转指令


伪指令resb


光标操作

屏幕上光标的位置保存在显卡内部的两个光标寄存器(8位)中,合起来是一个16位数值,表示在第几个位置(\(0 \sim {(80 * 25) - 1}\))。

注意:文字模式下,屏幕显示80*25个字符。

读取光标:

步骤:

  1. 向端口号0x3d4的索引寄存器指定索引,0xe是光标位置的高8位,0xf是光标位置的低8位。
  2. 通过端口号0x3d5的数据寄存器读取数据。

设置光标:

步骤:

  1. 向端口号0x3d4的索引寄存器写入光标位置的索引。
  2. 向端口号0x3d5的数据寄存器写入光标位置。

乘法

mul指令

mul 寄存器/[内存地址]

cpuid指令

用于返回处理器的标识和特性信息。

在eax寄存器中指定要返回CPU信息。返回结果放在eax、ebx、ecx或edx中。


eflags寄存器

image-20220126165237566


comvcc指令

可以看成mov指令加上条件判断功能,与cmptest指令配合使用。

伪代码:

if (condition) {
    mov dest, source
}

sgdt指令

格式:sgdt 寄存器/[内存单元]

把gdtr寄存器的内容保存到指定位置。


movzx/movsx指令


cmps指令

cmp指令的升级版,通过cx(16位)或ecx(32位)寄存器来指定比较次数,ds:si/esi寄存器指定源地址,es:di/edi寄存器指定目的地址,并根据eflags寄存器中的df位来决定地址变化的方向,\(df=0\)则正向比较,地址递增,\(df=1\)则反向比较,地址递减,如果没有加上rep指令前缀,则只比较一次。

cmpsb ;字节比较
cmpsw ;字比较
cmpsd ;双字比较

有关的rep指令前缀:

image-20220126173106954


调用门

调用门(Call Gate)用于不同特权级的程序之间进行控制转移。本质上只是一个描述符(不同于代码段和数据段)。

image-20220126200038307

调用门的特权级检查规则:

image-20220126203513197


pushf/popf指令

把16位的flags寄存器/32位的eflags寄存器压或弹栈到flag寄存器中。


GDT、LDT和TSS的关系

image-20220126204826235


任务切换与特权级切换的区别

image-20220126205808314


任务门

image-20220126210543989

image-20220126211109269

注意:任务是不可重入的。

任务切换:


页目录项和页表项的结构

image-20220127171112427

参数解释:

参数 含义
P 该页表/页是否存在于内存中,1存在,0不存在
RW 读写位,0该页只读,1可读可写
US 用户/管理位,1允许所有特权级访问,0只允许特权级为0、1、2的程序访问
PWT 页级通写位,与高速缓存相关
PCD 页级高速缓存禁止位
A 访问位,表示该页是否被访问过
D 脏位,表示该页是否被写过
PAT 页属性表支持位,与高速缓存相关
G 全局位,表示该页是否为全局性的,如果是,则一直保留在高速缓存中
AVL 被处理器忽略,软件可使用

CR3寄存器的内容

image-20220127175857850


bts指令

将指定位置的bit设置为1,并将其旧值设置到eflags寄存器的CF位中。

格式:

bts r/m16, r16
bts r/m32, r32

保护模式下的中断和异常向量分配

在实模式下,是由中断向量表定义了中断的入口地址(位于内存最低端的1KB),而保护模式下,是由中断描述符表(IDT)定义了中断的入口。(由idtr寄存器指定了中断描述符表所在位置)

中断描述符表里面保存了中断门、陷阱门和任务门。

image-20220127203910140

中断门、陷阱门:

image-20220127204617586

中断描述符寄存器:

image-20220127204549991

保护模式下的中断处理过程:

image-20220127204822859

保护模式下通过中断实现任务切换:

image-20220127205126792


bound指令

用于检查数组是否超出索引(这个数组是指源操作数所指向的内存单元里面存放了上限和下限,大小为双字)

格式:

bound r16, m16
bound r32, m32

ud2指令

该指令无操作数,执行该指令会引发一个无效操作码异常。

格式:

ud2

标签:保护模式,x86,16,地址,指令,偏移,内存,从实,寄存器
来源: https://www.cnblogs.com/Lht1/p/15851258.html