x86 汇编语言:从实模式到保护模式

1.逻辑地址的作用:程序在内存中加载的位置变了,仍然可以执行。
为了在硬件一级提供对“段地址:偏移地址”内存访问模式的支持,处理器至少要提供两个段寄存器,分别是代码段(Code Segment,CS)寄存器和数据段(Data Segment,DS)寄存器。对 CS 内容的改变将导致处理器从新的代码段开始执行。同样,在开始访问内存中的数据之前,也必须首先设置好 DS 寄存器,使之指向数据段。除此之外,最重要的是,当处理器访问内存时,它把指令中指定的内存地址看成是段内的偏移地址,而不是物理地址。这样,一旦处理器遇到一条访问内存的指令,它将把 DS 中的数据段起始地址和指令中提供的段内偏移相加,来得到访问内存所需要的物理地址。
2.指令预取队列
x86 汇编语言:从实模式到保护模式_第1张图片
3.逻辑分段按16字节对齐的原因:如果你从物理内存地址 82255H 处加载程序,由于它根本无法表示
成一个偏移地址为 0000H 的逻辑地址,所以不符合要求,段不能从这里开始划分。这里面的区
别在于,82260H 可以被十进制数 16(或者十六进制数 10H)整除,而 82255H 不能。通过这
个例子可以看出,8086 处理器的逻辑分段,起始地址都是 16 的倍数,这称为是按 16 字节对齐
的。
段的划分是自由的,它可以起始于任何 16 字节对齐的位置,也可以是任意长度,只要不
超过 64KB。比如,段地址可以是 82260H,段的长度可以是 64KB。在这种情况下,该段所对
应的逻辑地址范围是 8226H:0000H~8226H:FFFFH,其所对应的物理地址范围是 82260~
9225FH。
同时,正是由于段的划分非常自由,使得 8086 的内存访问也非常随意。同一个物理地址,
或者同一片内存区域,根据需要,可以随意指定一个段来访问它,前提是那个物理地址位于该
段的 64KB 范围内。也就是说,同一个物理地址,实际上对应着多个逻辑地址。
如果你从物理内存地址 82255H 处加载程序,由于它根本无法表示
成一个偏移地址为 0000H 的逻辑地址,所以不符合要求,段不能从这里开始划分。这里面的区
别在于,82260H 可以被十进制数 16(或者十六进制数 10H)整除,而 82255H 不能。通过这
个例子可以看出,8086 处理器的逻辑分段,起始地址都是 16 的倍数,这称为是按 16 字节对齐
的。
段的划分是自由的,它可以起始于任何 16 字节对齐的位置,也可以是任意长度,只要不
超过 64KB。比如,段地址可以是 82260H,段的长度可以是 64KB。在这种情况下,该段所对
应的逻辑地址范围是 8226H:0000H~8226H:FFFFH,其所对应的物理地址范围是 82260~
9225FH。
同时,正是由于段的划分非常自由,使得 8086 的内存访问也非常随意。同一个物理地址,
或者同一片内存区域,根据需要,可以随意指定一个段来访问它,前提是那个物理地址位于该
段的 64KB 范围内。也就是说,同一个物理地址,实际上对应着多个逻辑地址。
4.x86 汇编语言:从实模式到保护模式_第2张图片
5.硬盘
x86 汇编语言:从实模式到保护模式_第3张图片
扇区头包含了每个扇区自己的信息,主要有本扇区的磁道号、磁头号和扇区号,用来
供硬盘定位机构使用。现代的硬盘还会在扇区头部包括一个指示扇区是否健康的标志,以及用
来替换该扇区的扇区地址。用于替换扇区的,是一些保留和隐藏的磁道。
6.在屏幕上显示文字
显卡控制显示器的最小单位是像素,一个像素对应着屏幕上的一个点。屏幕上通常有数十万乃至更多的像素,通过控制每个像素的明暗和颜色,我们就能让这大量的像素形成文字和美丽的图像。
x86 汇编语言:从实模式到保护模式_第4张图片
现在最流行的,是用 24 个比特,即 3 个字节,来对应一个像素。因为 2^24=16777216,所以在这种模式下,同屏可以显示 16777216 种颜色,这称为真彩色。
x86 汇编语言:从实模式到保护模式_第5张图片
在计算机中,每个用来显示在屏幕上的字符,都有一个二进制代码。这些代码和普通的二进制数字没有什么不同,唯一的区别在于,发送这些数字的硬件和接收这些数字的硬件把它们解释为字符,而不是指令或者用于计算的数字。
x86 汇编语言:从实模式到保护模式_第6张图片

//将L送到屏幕上
mov ax,0xb800
mov es,ax
mov byte [es:0x00],'L' //等效于:mov byte [es:0x00],0x4c,
在源程序的编译阶段,汇编语言编译器会将它转换成 ASCII 码的形式。
mov byte [es:0x01],0x07 //黑底白字,无闪烁,无加亮

7.段之间的批量数据传送
movsb 和 movsw 指令执行时,原始数据串的段地址由 DS 指定,偏移地址由 SI 指定,简写为DS:SI;要传送到的目的地址由 ES:DI 指定;传送的字节数(movsb)或者字数(movsw)由 CX 指定。除此之外,还要指定是正向传送还是反向传送,正向传送是指传送操作的方向是从内存区域的低地址端到高地址端;反向传送则正好相反。正向传送时,每传送一个字节(movsb)或者一个字(movsw),SI 和 DI 加 1 或者加 2;反向传送时,每传送一个字节(movsb)或者一个(movsw)时,SI 和 DI 减去 1 或者减去 2。不管是正向传送还是反向传送,也不管每次传送的是字节还是字,每传送一次,CX 的内容自动减一。
8.计算1+2+……+100,并打印

jmp near start
message db '1+2+3+...+100='

start:
         mov ax,0x7c0           ;设置数据段的段基地址
         mov ds,ax
         mov ax,0xb800          ;设置附加段基址到显示缓冲区
         mov es,ax

         ;以下显示字符串
         mov si,message         
         mov di,0
         mov cx,start-message
     @g:
         mov al,[si]
         mov [es:di],al
         inc di
         mov byte [es:di],0x07
         inc di
         inc si
         loop @g

         ;以下计算1100的和
         xor ax,ax
         mov cx,1
     @f:
         add ax,cx
         inc cx
         cmp cx,100
         jle @f

         ;以下计算累加和的每个数位
         xor cx,cx              ;设置堆栈段的段基地址
         mov ss,cx
         mov sp,cx
         mov bx,10
         xor cx,cx
     @d:
         inc cx
         xor dx,dx
         div bx
         or dl,0x30 //数字的二进制码,为num+00110000;
         push dx
         cmp ax,0
         jne @d
         ;以下显示各个数位
     @a:
         pop dx
         mov [es:di],dl
         inc di
         mov byte [es:di],0x07
         inc di
         loop @a
         jmp near $

times 510-($-$$) db 0
                 db 0x55,0xaa
//times 510-($-$$) db 0 表示填充 510-($-$$) 这么多个字节的0
这里面的$表示当前指令的地址,$$表示程序的起始地址(也就是最开始的7c00),所以$-$$就等于本条指令之前的所有字节数。510-($-$$)的效果就是,填充了这些0之后,从程序开始到最后一个0,一共是510个字节。再加上最后的dw两个字节(0xaa55是结束标志),整段程序的大小就是512个字节,刚好占满一个扇区。

9.光标
光标(Cursor)是在屏幕上有规律地闪动的一条小橫线,通常用于指示下一个要显示的字符位置,这对很多年龄比较大的人来说很熟悉(前提是他们以前也用过计算机)。在那个时代,还没有基于图形显示技术的 Windows,所有的软件都在文本模式下工作,而基于硬件的光标只在文本模式下才会出现。
10.中断
中断就是打断处理器当前的执行流程,去执行另外一些和当前工作不相干的指令,执行完之后,还可以返回到原来的程序流程继续执行。这就好比是你正在用手机听歌,突然来电话了。处理器(当然,手机也是有处理器的)必须中断歌曲的播放,来处理这件更为重要的事件。
11.实时时钟
实时时钟是全天候跳动的,即使是在你关闭了计算机的电源之后,原因在于它由主板上的一个小电池提供能量。它为整台计算机提供一个基准时间,为所有需要时间的软件和硬件服务。


12.32位模式
在 32 位模式下,对内存的访问从理论上来说不再需要分段,因为它有 32 根地址线,可以自由访问任何一个内存位置。但是,IA-32 架构的处理器是基于分段模型的,因此,32 位处理器依然需要以段为单位访问内存,即使它工作在 32 位模式下。
不过,它也提供了一种变通的方案,即,只分一个段,段的基地址是 0x00000000,段的长度(大小)是 4GB。在这种情况下,可以视为不分段,即平坦模型(Flat Mode)。
在 32 位模式下,处理器要求在加载程序时,先定义该程序所拥有的段,然后允许使用这些段。定义段时,除了基地址(起始地址)外,还附加了段界限、特权级别、类型等属性。当程序访问一个段时,处理器将用固件实施各种检查工作,以防止对内存的违规访问。在 32 位模式下,传统的段寄存器,如 CS、SS、DS、ES,保存的不再是 16位段基地址,而是段的选择子,即,用于选择所要访问的段,因此,严格地说,它的新名字叫做段选择器。除了段选择器之外,每个段寄存器还包括一个 64 位的不可见部分,称为描述符高速缓存器,里面有段的基地址和各种访问属性。这部分内容程序不可访问,由处理器自动使用。
13.http://www.cnblogs.com/tgycoder/p/6116690.html 分页看这个
14.乱序执行

x86 汇编语言:从实模式到保护模式_第7张图片
15.寄存器重命名
x86 汇编语言:从实模式到保护模式_第8张图片
16.分支目标预测
x86 汇编语言:从实模式到保护模式_第9张图片
17.补充的操作
1.shl dword [eax*2+0x08],cl 2.idiv r/m32//被除数是 64 位的,高 32 位在 EDX 寄存器;低 32 位在 EAX 寄存器。除数是 32 位的,位于 32 位的寄存器,或者存放有 32 位实际操作数的内存地址。指令执行后,32 位的商在 EAX 寄存器,32 位的余数在 EDX 寄存器。
3.push byte 0x55
18.全局描述符表
在保护模式下,对内存的访问仍然使用段地址和偏移地址,但是,在每个段能够访问之前,必须先进行登记。
x86 汇编语言:从实模式到保护模式_第10张图片

你可能感兴趣的:(汇编与硬件)