花褪残红青杏小。燕子飞时,绿水人家绕。

PC机中的寄存器

菜鸟编程 十五楼的鸟儿 29425浏览 1评论

差点把学了几天的86汇编给荒废掉,抓紧捡起来。先看看PC机中的寄存器。

编制程序前我们应首先调入DEBUG。很简单,在DOS提示符下敲入DEBUG并回车即可。随着磁盘的转动,DEBUG被装入内存执行。一番忙碌后,屏幕上将出现一个"-",后面是跳动的光标。

屏幕上出现的"-"其实是DEBUG给出的提示符,它的出现说明DEBUG此时已经完全作好了为你服务的准备。和DOS一样,DEBUG也提供了一个"命令行"界面,只有输入它自己定义的一些命令才能调动它好好工作。现在我们就来试着打入一个命令--在"-"后面敲入一个字母"R"并回车,看看屏幕上出现些什么东西?

"R"命令的作用是"列出寄存器目前所存的数值",字母"R"取自单词Register。这个命令可以加一个寄存器名做为参数,如RBX、RDI等,其中 BX,DI都是寄存器的名字(见下文)。使用这种用法时不仅可以观察某个寄存器的值,还可以任意修改寄存器的内容。有关实例将在后面给出。

  (1) 通用寄存器(General register)   8086/88内部有14个寄存器。其中有四个寄存器最常用。这四个寄存器称为通用寄存器。名字分别是AX、BX、CX和DX。它们具有一个通用的功能--保存数据,但每个寄存器还有自己专门的用途,下面分别介绍。

AX:A取自单词Accumulator,所以AX也被称为"累加器"。不过请不要望文生意,它的专门用途可不是作加法。今天我们介绍它的一个专门用途,就是CPU与端口交换数据的唯一通路。除此之外,它还有一系列专门的用途,这些用途以后会陆续谈到。

BX:BX也被称为"基地址寄存器"(Base address)。这也是一个十分重要的寄存器,它可用来作为指针使用。这方面的内容将在第三章介绍。本节的程序不涉及BX的专门用途。

CX;CX也称"计数器"(Counter)。这个寄存器主要用于为循环指令(LOOP)计循环次数,也用于计数据移位的位数。在"串处理"指令中也有应用。后面的程序就是用CX为LOOP指令计数的。

DX:DX是一个一般用途的数据寄存器,通常用于临时保存数据。有时它也和AX一起应用,用于记录32bit数据的高16bit。同时DX在端口输入/输出时也有特殊用途,此用途将在后交介绍。

 前面所讲的四个寄存器都是16位的,有时程序也需要使用8位的数据,因此,这四个16位通用寄存器都可以拆分成两个8位寄存器。即它们的高8位和低8位可单独使用。这两个部分都有专门的名字,我们用字母"H(High)"表示高8位,用"L(Low)"表示低 8位。因此,对于AX来讲,它的高8位被称为AH,低8位称为AL。同理,BX、CX、DX均可分成"*H"、"*L"分别使用。

(2) 逻辑地址   出现在左下角的16进制数字就是目前即将存放程序代码的内存起始地址。在前面一章里讨论数据存储时曾说到过,每个内存单元都有一个地址。对于8086/88来说,它的内存地址范围是 00000--0FFFFFH。即它产生20位的地址。这20位的地址我们一般称其为"物理地址"。 PC机中的寄存器 汇编 ASM 菜鸟编程  第1张 但实际上CPU内部并没有20位的寄存器来保存它所需的地址,这是因为在一个硅片上制造20位的寄存器是很不方便的。因此在设计8086/88时,技术人员对这1MB的内存做了如下所述的重新编排。

  首先,我们把1MB内存分成了一些相互重叠的存储块,从地址00000开始,每隔16个字节做为一个块的开始,整个内存分为64K个块,这些存储块被称为"存储段"。

每个块的长度是64KB。对于相邻的两段而言,前一段的后64K-16个字节和后一段的前64K-16字节是重叠的。

每一个段都有一个编号,这个编号就是"段地址"。因此如果想找到内存中的某一单元,首先应给出这个单元所在的任一个段的段地址,然后再给出这个单元在所选段内的"偏移量"(距段首的距离),就可找到这个内存单元。

习惯上一般把这种用"段地址:偏移量"表示内存单元所在位置的形式称为"逻辑地址"。因为各个段间有部分重叠,所以同样的一个内存单元有多种不同的"段:偏移"表示。例如对于物理地址为00010H的内存单元,若在内存第0段中表示,应该是0000:0010H;而在内存第1段中表示,则成了0001:0000H。

逻辑地址和物理地址之间的转换转换关系也很简单,由于段地址起始于16字节的整数倍,因此若要找到某个段的起始地址,只须将该段的段地址乘以16即可;不同的单元有不同的段内偏移量,将偏移量和段起始物理地址相加,就得到任一内存单元的物理地址。

例如逻辑地址0000:0010H对应的物理地址是0′10H+10H=00010H;而逻辑地址0001:0000对应的物理地址是1′ 10H+0=00010H,这两个逻辑地址表示内存中同一个单元。注意这种转换是由CPU内部电路自动完成的,对于汇编程序而言则只需使用逻辑地址即可。

(3) 段寄存器(Segment register)

段寄存器就是用来存储内存单元的段地址的。CPU中共有四个段寄存器DS、ES、CS和SS,分别介绍如下:

DS:DS称为数据段地址寄存器(Data segment),它保存数据段的段地址。如果在程序中有数据的存取操作时,若不"显式"地指定段寄存器,则将在DS指定的段寻找相应的存储单元。

ES:ES称为附加段地址寄存器(Exterial segment),也可以称为扩展段地址寄存器,它用于指向内存中的任一段。一般情况下我们常使用这个段寄存器取得内存中某个单元的数据而不需修改DS寄存器。

CS:CS是代码段地址寄存器(Code segment),它和IP(指令指针)寄存器一起指向目前正在执行的指令。也就是说,CPU永远在IP指向的内存单元中取得指令机器码并执行。CS寄存器的数值有变化,CPU所取的指令就有变化。

SS:SS是堆栈段地址寄存器(Stack segment),它保存了堆栈存储区的段地址。堆栈是开辟在内存中的一段特殊空间,数据在堆栈中存取不同于在其它内存空间。有关堆栈的概念将在后面做更详细地介绍。

以上所讲的所有段寄存器都是16位的,无法拆分成8位使用,同时,段寄存器不能参与任何数学运算和逻辑操作。

(5) 指令指针寄存器(Instruction Pointer)

IP是CPU内部一个16位的寄存器,它用于记录CPU将要执行的指令的偏移地址。指令的段地址由CS保存。IP不同于其它寄存器,它不能随意的修改,不能参与任何运算或逻辑操作。它的唯一用途就是为CPU取得指令提供偏移地址(CS提供段地址)。也就是说,CPU永远从CS:IP指定的内存地址处取得所要执行的指令。

如果CS:IP指向的位置没有合乎逻辑的指令,而是一些杂乱无章的数据,那么CPU就会傻乎乎地把这些乱七八糟的数据当成指令来胡乱执行,其结果将是未知的。通常情况下会导致"死机"。

在进入DEBUG环境后IP究竟指向什么位置?屏幕上显示IP指向偏移100H的位置。也就是说,我们后面要编制的程序也必须从偏移100H处开始。为什么要空出前面256字节内存呢?这是因为在这256字节的内存中保存有DOS系统提供的重要数据。关于这些数据的说明会在后面陆续介绍。

(6)变址、基指针、堆栈指针和标志寄存器(Index,Base Po
inter,Stack Point & Flag)

这部分内容现在暂时不用,后面用到时会详细加以说明。

一个看似简单的R命令引出了这么多枯燥的东西,实在让人头痛。不过这可是些极其重要的基本知识,不了解这些细节内容就无法继续学习下去。

实际上与学习高级语言相比,这些知识更应使人感到新奇有趣。毕竟,我们只能看到高级语言执行的结果,而看不到它执行的过程。


转载请注明:鸟儿博客 » PC机中的寄存器

游客
发表我的评论 换个身份
取消评论

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址

网友最新评论 (1)

  1. 访客
    江宁余鹏程 5年前 (2019-11-04)回复