x86笔记-第 2 章 处理器、内存和指令

bit、Byte、word和double word之间的关系换算

1 字节(Byte)= 8 比特(bit)
1 字(word)= 2 字节(Byte)= 16 比特(bit)
1 双字(double word)= 4 字节(Byte)= 32 比特(bit)

  • 处理器总是很繁忙的,在它操作的过程中,所有数据在寄存器里面都只能是临时存在一会儿,然后再被送往别处,这就是为什么它被叫做“寄存器”的原因。早期的处理器,它的寄存器只能保存4 比特、8 比特或 16 比特,它们分别叫做 4 位、8 位和 16 位寄存器。现在的处理器,寄存器一般都是 32 位、64位甚至更多。

如图 2-3 所示

  • 8 位寄存器可以容纳 8 比特(bit),或者说 1 字节(Byte),这是因为 1 byte = 8 bit
    另外,我们还要为这个字节的每一位编上号,编号是从右往左进行的,从 0 开始,分别是 0、1、2、3、4、5、6、7。在这里,位 0(第 1 位)是最低位,在最右边;位 7(第 8 位)是 最高位,在最左边。
  • 16 位寄存器可以存放 2 个字节,这称为 1 个字(word),各个数位的编号分别是 0~15, 其中 0~7 是低字节,8~15是高字节。实际上,“字”的概念出现得很早,也并非指 16 个比特。 只是到了后来,才特指 16 个二进制位的长度。
  • 32 位寄存器可以存放 4 个字节,这称为 1 个双字(double word),各个数位的编号分别 是 0~31,其中 0~15是低字,16~31 是高字。

图2-3

内存储器

如图 2-5 所示,内存用于保存更多的比特。对于用得最多的个人计算机来说,内存按字节来组织,单次访问的最小单位是 1字节,这是最基本的存储单元。

内存储器存储数据的 最基本的单位字节(Byte)
内存储器存储数据的 最小的单位位(bit,又称 比特)

  • 内存中的每字节都对应着一个地址,如图 2-5 所示,第 1 个字节的地址是 0000H,第 2 个字节的地址是 0001H,第 3 个字节的地址是 0002H,其他依次类推。注意,这里采用的是十六进制表示法(“H” 是英语单词 Hexadecimal 的首字母, 表示十六进制)。作为一个例子,因为这个内存的容量是65536 字节,所以最后一个字节的地址是FFFFH。
  • 处理器发出字长控制信号,以指示本次访问的字长是 8、16、32 还是 64。如果字长是 8,而且给出的地址是 0002H,那么,本次访问只会影响到内存的一字节;如果字长是 16,给出的地址依然是 0002H,那么实际访问的将是地址 0002H 处的一个字,低 8 位在0002H 中,高 8 位在 0003H 中。

图2-5

指令和指令集

简单介绍

  • 处理器的设计者用某些数来指示处理器所进行的操作,这称为指令(Instruction),或者叫机器指令,因为只有处理器才认得它们。
  • 比如,指令F4H表示让处理器停机,当处理器取到并执行这条指令后,就停止工作。
  • 指令是集中存放在内存里的,一条接着一条,处理器的工作是自动按顺序取出并加以执行。
  • 一般来说,指令由操作码和操作数构成,但也有小部分指令仅有操作码,而不含操作数。对处理器来说,指令的操作码隐含了如何执行该指令的信息,比如它是做什么的,以及怎么去做。
  • 一个处理器能够识别的指令的集合,称为该处理器的指令集。

如图 2-6 所示,从内存地址 0000H 开始(也就是内存地址的最低端)连续存放了一些指令。 同时,假定执行这些指令的是一个 16 位处理器,拥有两个 16 位的寄存器 RA 和 RB。

操作码中隐含了许多信息,处理器就可以“知道”每条指令的长度。

注意字数据在内存中的存放特点。地址 0001H 和 0002H 里的内容分别是 5D 和 00,如果每次读一个字节,则从地址 0001H里读出的是 5D,从 0002H 里读出的是 00。但如果以字的方式来访问地址 0001H,读到的就会是005DH。
这种差别,跟处理器和内存之间的数据线连接方式有关。对于 Intel 处理器来说,如果访问内存中的一个字,那么,它规定高字节位于高地址部分,低字节位于低地址部分,这称为低端字节序(Little Endian)。至于其他公司的处理器,则可能情况正好相反,称为高端字节序
图2-6

立即数

  • 指令的操作数部分是 3F 00,指定了一个内存地址 003FH。它相当于高级语言里的指针,当处理器执行这条指令时,会再次用 003FH 作为地址去访问内存,从那里取出一个字(1002H),然后将它复制到寄存器 RB。
  • 指令执行和操作的对象是数。如果这个数已经在指令中给出了,不需要再次访问内存,那这个数就是立即数,比如第一条指令中的 005DH;相反,如果指令中给出的是地址,真正的数还需要用这个地址访问内存才能得到,那它就不能称为立即数,比如第二条指令中的 003FH。

古老的 Intel 8086 处理器

8086 的通用寄存器

  • 8086 处理器内部有 8 个 16 位的通用寄存器,分别被命名为 AX、BX、CX、DX、SI、DI、BP、SP。“通用”的意思是,它们之中的大部分都可以根据需要用于多种目的。

如图 2-7 所示,这 8 个寄存器中的前 4 个,即 AX、BX、CX 和 DX,又各自可以拆分成两个 8 位的寄存器来使用,总共可以提供 8 个 8 位的寄存器 AH、AL、BH、BL、CH、CL、DH 和 DL(可将高位记为Height,低位记为Low)。
这样以便在寄存器和寄存器之间,或者寄存器和内存单元之间进行 8 位的数据传送或者算术逻辑运算。
图2-7
将一个 16 位的寄存器当成两个 8 位的寄存器来用时,对其中一个 8 位寄存器的操作不会影响到另一个 8 位寄存器。举个例子来说,当你操作寄存器 AL 时,不会影响到 AH 中的内容。

扫描二维码关注公众号,回复: 10245395 查看本文章

程序的重定位难题

为了让你写的程序在卖给别人之后,可以在内存中的任何地方正确执行,就只能在编写程序的时候使用相对地址或者逻辑地址了,而不能使用真实的物理地址。当程序加载时,这些相对地址还要根据程序实际被加载的位置重新计算。

内存分段机制

  • 如图 2-10 所示,整个内存空间就像长长的纸条,在内存中分段,就像从长纸条中裁下一小段来。
  • 在这个例子中,分段开始于地址为 A532H 的内存单元处,这个起始地址就是段地址。 这个分段包含了6个存储单元。在分段之前,它们在整个内存空间里的物理地址分别是A532H、A533H、A534H、A535H、A536H、A537H。
  • 但是,在分段之后,它们的地址可以只相对于自己所在的段。这样,它们相对于段开始处的距离分别为0、1、2、3、4、5,这叫做偏移地址
  • 于是,当采用分段策略之后,一个内存单元的地址实际上就可以用“段:偏移”或者“段地址:偏移地在这里插入代码片址”来表示,这就是通常所说的逻辑地址
  • 比如,在图 2-10 中,段内第 1 个存储单元的地址为 A532H:0000H,第 3 个存储单元的地址为 A532H:0002H,而本段最后一个存储单元的地址则是 A532H:0005H。

图2-10
为了在硬件一级提供对“段地址:偏移地址”内存访问模式的支持,处理器至少要提供两个段寄存器,分别是代码段(Code Segment,CS)寄存器数据段(Data Segment,DS)寄存器
当处理器访问内存时,它把指令中指定的内存地址看成是段内的偏移地址,而不是物理地址。这样,一旦处理器遇到一访问内存的指令,它将把 DS 中的数据段起始地址和指中提供的段内偏移相加,得到访问内存所需要的物理地址。

IP 是指令指针(Instruction Pointer)寄存器,它只和 CS 一起使用,而且只有处理器才能直接改变它的内容。当一段代码开始执行时,CS 指向代码段的起始地址,IP 则指向段内偏移。这样,由 CS 和 IP 共同形成逻辑地址,并由总线接口部件变换成物理地址来取得指令。然后,处理器会自动根据当前指令的长度来改变 IP 的值,使它指向下一条指令。

比如,对于逻辑地址 F000H:052DH,处理器在形成物理地址时,将段地址 F000H 左移 4 位,变成 F0000H,再加上偏移地址 052DH,就形成了 20 位的物理地址 F052DH。

CS × 16 + IP = CPU将要执行代码的该物理内存地址

资料参考

  • 《x86 汇编语言:从实模式到保护模式》
发布了29 篇原创文章 · 获赞 42 · 访问量 8508

猜你喜欢

转载自blog.csdn.net/qq_43068326/article/details/104249022
今日推荐