【汇编】寄存器(学习笔记)

一、CPU工作原理

1、CPU概述

CPU由运算器、控制器、寄存器等器件组成,这些器件靠内部总线相连。

内部总线:CPU内部 <–> 各个器件

外部总线:CPU <–> 主板上其它器件

2、通用寄存器

8086CPU所有的寄存器都是16位的,可以存放两个字节(一个字)。

8086CPU有14个寄存器:AX、BX、CX、DX、SI、DI、SP、BP、IP、CS、SS、DS、ES、PSW。

AX、BX、CX、DX 通常用来存放一般性数据被称为通用寄存器。

8086上一代CPU(8088)中的寄存器都是8位的。

为保证兼容性,这四个寄存器都可以分为两个独立的8位寄存器(AX --> AH、AL)使用。

AH:高位、AL:低位

【汇编】寄存器(学习笔记)_第1张图片

3、字在寄存器中的存储

1Word(字)= 2Byte(字节)= 16bit(比特)

一个字可以存在一个16位寄存器中,这个字的高位字节和低位字节自然就存在这个寄存器的高8位寄存器和低8位寄存器。

由于一个内存单元可以存放8位数据,CPU中的寄存器又可存放n个8位数据。计算机中的数据大多是由多个8位数据构成的

用十六进制来表示数据可以直观的看出这个数据是由哪些8位数据构成的。

在十六进制表示的数据的后面加 H,在二进制表示的数据后面加 B,十进制表示的数据后面什么也不加

4、汇编指令初识

汇编指令不区分大小写

汇编指令 高级语言描述
mov ax,18(后面给前面赋值) AX = 18
add ax,8 AX = AX + 8

丢失进位:进位制不能在8位寄存器中保存,但是CPU不是并真的不丟弃这个进位值

5、物理地址

跟mac地址的物理地址不同

CPU访问内存单元时要给出内存单元的地址

所有的内存单元构成的存储空间是一个一维的线性空间 --> 物理地址

6、16位结构的CPU

16位结构的CPU 特征:

  1. 运算器一次最多可以处理16位的数据
  2. 寄存器的最大宽度为16位
  3. 寄存器和运算器之间的通路是16位的

7、8086给出物理地址的方法

8086有20位地址总线,可传送20位地址,寻址能力为1M( 2 20 = 1 M B 2^{20}=1MB 220=1MB)。但是8086内部为16位结构,它只能传送16位的地址,表现出的寻址能力却只有64k( 2 16 = 64 K B 2^{16}=64KB 216=64KB

8086CPU采用一种在内部用两个16位地址合成的方法来开成一个20位的物理地址

CPU中的相关部件提供两个16位的地址,一个称为段地址,另一个称为偏移地址

【汇编】寄存器(学习笔记)_第2张图片

段地址和偏移地址通过内部总线送入一个称为"地址加法器"的部件

地址加法器将两个16位地址合并成一个20位的地址(段地址 x 16 + 偏移地址 = 物理地址

8、"段地址+偏移量"的本质

”段地址×16“ --> 二进制位左移4位

一个数据的二进制形式左移n位,相当于该数据乘上2的n次方

一个数据的n进制形式左移1位,相当于乘以n

9、段的概念

内存没有分段

段的划分来自于cpu:由于8086CPU "段地址 x 16 + 偏移地址"的方式给出物理地址,使得我们可以用分段的方式管理内存

编程时可以将若干地址连续的内存看成一个段,用段地址x16定位段的起始地址(基础地址),用段偏移地址定位段中的内存单元

  1. 段的起始地址一定是16的倍数
  2. 16位地址的寻址能力为64位 --> 一个段的最大长度为64K

CPU可以用不同的段地址和偏移地址形成一个物理地址

寻址范围:0~FFFFH

10、段寄存器

段寄存器:提供段地址

8086CPU有四个段寄存器:CS、DS、SS、ES

11、CS、 IP

CS和IP是8086CPU中最关键的寄存器,它指示了CPU当前要读取指令的地址。

CS:代码段寄存器(段地址)

IP:指令指针寄存器(偏移地址)

【汇编】寄存器(学习笔记)_第3张图片

8086工作过程简要

  1. 从CS、IP指向内存单元读取指令,读取的指令进入指令缓冲区
  2. IP = IP + 所读取指令的长度,从而指向下一条指令

12、CS:IP的修改

1)转移指令

转移指令jump:修改CS、IP的值

jump 段地址:偏移地址

2)修改IP

jmp:修改寄存器中的值

jmp 某一合法寄存器

13、代码段

代码段:用来存放程序执行代码的一块内存区域

CPU只认被CS:IP指向的内存单元中的内容为指令 --> 将CS:IP指向所定义的代码段中的第一条指令的首地址

二、内存访问

1、内存中字的存储

任何两个地址连续的内存单元,N号单元和 N+1号单元,可以将它们看成两个内存单元,也可以看成一个地址为N的字单元中的高位字书单元和低位字节单元。

2、DS和[address]

CPU读取内存需要内存单元的地址

8086有一个DS寄存器,用来存放需要读取的内存的地址

mov bx,1000H
mov ds,bx
mov al,[0]

mov al,[0]:将段地址为ds、内存偏移地址为0的内容放到寄存器

数据 -> 通用寄存器 -> 段寄存器

8086不能直接将数据直接放入段寄存器(mov ds,1000H

3、move、add、sub指令

1)move

=

move 寄存器,数据
move ax, 6

move 寄存器,寄存器
move bx, ax

move 寄存器,内存单元
move ax, [0]

move 内存单元,寄存器
move [0], ax

move 段寄存器,寄存器
move ds, ax

move 寄存器,段寄存器
move ax, ds

2)add

+=

add 寄存器,数据
add ax, 6

add 寄存器,寄存器
add bx, ax

add 寄存器,内存单元
add ax, [0]

add 内存单元,寄存器
add [0], ax

3)sub

-=

sub 寄存器,数据
sub ax, 6

sub 寄存器,寄存器
sub bx, ax

sub 寄存器,内存单元
sub ax, [0]

sub 内存单元,寄存器
sub [0], ax

5、数据段

数据段:将一组长度为N(N≤64K)、地址连续、起始地址为16的倍数的内存单元当作专门存储数据的内存空间

6、栈

栈特性:FILO(先进后出,后进先出)

两个基本操作:入栈、出栈

push ax
pop ax

8086出栈入栈都以字为单位进行

1、CPU怎么知道的哪里是栈?
2、执行push和pop时候,如何知道那个单元是栈顶单元?

8086CPU中,存在段寄存器SS(存放栈顶的段地址)、段寄存器SP(存放栈顶的偏移地址)

任意时刻,SS:SP指向栈顶元素

7、栈机制

pop只会移动SS:SP(指针),不会删除之前的值。

栈空时,栈中没有元素,不存在栈顶元素。SS:PP指向栈的最底部的字单元的偏移地址+2。

【汇编】寄存器(学习笔记)_第4张图片

8、栈顶越界问题

依靠SS和SP保证能找到栈顶,CPU也不知道栈空间有多大。栈顶可能会超出栈空间。

pop空栈、push满栈 --> 栈顶越界(溢出攻击)

CPU提供记录栈顶上限和下限的寄存器,每次pop和push做检查,但是8086并没有。

9、栈和内存

栈空间是内存的一部分,只是一段可以以特殊方式访问的内存空间。

10、栈段

栈段:将长度为N(N<=64K)的一组地址连续、起始地址为16的倍数的内存单元,当作栈来使用

栈段只是编程的概念,CPU只认识SS:SP。

你可能感兴趣的:(汇编,学习,笔记)