【汇编语言/底层开发】2、CPU的寄存器

寄存器是CPU中用于高速存取暂存数据的存储部件。通过改变寄存器中的数据,可以对CPU的行为进行控制。对于8086CPU,内部共有14个寄存器,位宽均为16位,分别是AX, BX, CX, DX, SI, DI, SP, BP, IP, CS, SS, DS, ES, PSW。不同的寄存器所起到的作用不同。

1、通用寄存器

      通用寄存器指的是AX, BX, CX, DX四个寄存器,可以用于存放通用数据。每一个通用寄存器可以存放16位数据,而由于上一代CPU的寄存器为8位,考虑到兼容性,每一个通用寄存器可以按照高八位和低八位分成两个8为寄存器,名称分别为xH和xL(如AH/AL等)。这分割出来的8位寄存器在使用中都是独立的寄存器。,在数据超过8位的时候会产生溢出。比如AL中的数据如果超过了8位,那么多余出来的位数并不会影响到AH中的数据。通过这样的寄存器结构,CPU可以一次性处理字节Byte和字Word(2字节)两种尺寸的数据。

2、简单汇编指令

      汇编语言的指令和寄存器名称不区分大小写。较常用的例如:

mov ax, 18 //将18H存入寄存器ax
add ax, bx //将寄存器bx的值与ax相加,存入ax

其实只需明白一点就是,操作的结果储存于两个操作数的前者就好了。另外需要注意的是, 两个操作对象的位数必须一致,例如mov ax, bl这样的指令就是错的。

3、CPU位数与物理地址

    现在的CPU主流已经是64位,部分老式机器是32位,而8086CPU是16位。对于8086而言,所谓16位CPU指的是,运算器的宽度为16位,即一次可以计算16位的数据,寄存器最大宽度是16位,二者之间的内部总线宽度也是16位。对于32位、64位机器则是同样的道理。

    8086的外部地址总线的宽度为20位,寻址能力为1M,因此在实际操作中,需要CPU用16位的数据表示20位的地址。为了实现这样的功能,8086通过提供了两个16位的地址:段地址和偏移地址,由地址加法器将短地址左移四位并与偏移地址相加来合成物理地址。通过这样的方式,CPU将内存地址看做一个整段+一个偏移量的方式来表示,也是因为这样的缘故,一个段的起始地址一定是16的倍数,长度最大是64KB。

4、段寄存器和指令指针寄存器

      8086包含四个段寄存器:CS, DS, SS, ES,分别作为代码段寄存器、数据段寄存器、堆栈段寄存器和额外段寄存器。另外IP寄存器作为指令指针寄存器。在任意时刻,CPU从CS×16+IP的内存地址中获取指令并执行,地址可以记为CS:IP。读取完成一条指令后,IP中的值可以根据刚刚读取指令的长度自动增加,使CPU可以轻易读取下一条指令。在刚刚启动时,CS和IP的初始状态为CS
= FFFFH,IP = 0000H。

      8086的工作流程如:

  1. 从CS:IP中读取指令,进入指令缓冲器;
  2. IP向下移动指令长度,指向下一条指令;
  3. 执行,循环这个过程。

      修改CS和IP寄存器采用jmp命令:

jmp MMM:NN //将CS修改为MMM,将IP修改为NN
jmp NN //不改动CS,将IP修改为NN
时间: 2024-11-11 03:10:25

【汇编语言/底层开发】2、CPU的寄存器的相关文章

【汇编语言/底层开发】11、标识寄存器

除了前述的多种具有特定用途的寄存器之外,8086的CPU中还存在一类特殊的寄存器,称为标识寄存器flag,其每一位可能用来存储特定的信息,主要有以下三类: (1)相关指令的某些执行结果: (2)为CPU执行相关指令提供依据: (3)控制CPU的相关工作方式. 在这个16位的寄存器中,共有9个bit位被用作某种标识位,其他几个bit为保留位,没有实际意义.以下几节中将浏览其中几个标志位的作用和使用方法. 1.ZF标识: ZF标识位为flag的第六位,其含义为0标识位.当某条汇编指令完成后,结果为0

【汇编语言/底层开发】3、通过寄存器进行内存访问

上篇叙述了8086CPU的通用寄存器和代码寄存器的一些东西.仅仅这些是远远不够的,显而易见的一个原因是,如果CPU只是对自己内部的寄存器进行操作,不能同外部数据进行交互,那么将无法完成任何工作. 数据段寄存器DS: 8086CPU中的DS寄存器专门用来存放准备访问的数据的段地址.[n]则表示一个偏移地址,这个偏移地址同DS中表示的段地址一起确定最终要访问的内存地址. 以下汇编语句表示从10000H地址中的数据读入寄存器AL中: MOV BX, 1000 MOV DS, BX MOV AL, [0

【汇编语言/底层开发】1、CPU的总线与存储器

1. 总线 CPU对存储器的读写操作是通过链接CPU同其他芯片的导线完成的,这样的导线即称作总线.根据传输的信息的不同,总线在逻辑上分为地址总线.控制总线和数据总线3大类. (1)地址总线: CPU通过地址总线指定存储器单元,地址总线上能传递多少不同信息,CPU就可以对多少个存储单元进行寻址.如果一个CPU有N根地址线,则其地址总线宽度为N,寻址能力为2^N个内存单元. (2)数据总线: 数据总线负责CPU同内存和其他器件之间的数据传送,其宽度决定了数据传送的速度.例如80x86的数据总线宽度为

【汇编语言/底层开发】5、[BX]和loop指令

1.[bx] 在之前编写的汇编代码中,我们经常使用到[0].[1]等标志,方括号中的数字表示某个偏移地址,该地址同段地址一起表示某个内存的位置.但是,在实际应用中存在一个问题,masm等编译器实际上不支持[n]这样的写法,在代码中的[1].[2]实际上会被处理成1.2等数字型常量,而不是我们希望的偏移地址. 为了解决这个问题,汇编语言中定义了[bx]的写法.bx中存放的数据被当做是一个偏移地址,相应的段地址保存于寄存器DS,二者共同构成一个内存中的实际地址.使用方式如下: mov ax, [bx

【汇编语言/底层开发】9、转移指令的原理

可以修改IP或者同时修改CS和IP的指令统称为转移指令.转移指令控制CPU执行内存中某处的代码,其作用相当于C语言中的GOTO.在C语言中并不鼓励使用goto语句,但是在汇编语言中由于没有复杂的流程控制运算符,使用转移指令称为必然.在8086中,转移指令可分为以下几类:(1)无条件转移指令:(2)条件转移指令:(3)循环指令:(4)过程:(5)中断. 1.操作符Offset: 操作符offset是由编译器处理的符号,功能是取得标号所在的偏移地址. 2.jmp指令: jmp为无条件跳转指令,可以修

【汇编语言/底层开发】6、程序中包含多个segment

众所周知的是,我们所开发的应用程序需依赖于操作系统运行,因此应用程序所使用的内存空间必须是安全的,不能与操作系统和其他应用程序相重合.因此,应用程序所需要的空间应当通过操作系统申请.对于我们使用汇编语言开发的程序而言,可以通过在源程序中定义段来获取内存空间. 1.在代码段中定义数据 在编写汇编程序时,可以直接在代码段中对数据进行定义.使用dw可以定义若干个字型数据,每个数据占据两个字节.但是由此带来的问题就是,代码段中的所有数据在运行时都会当做指令代码进行处理,因此我们使用dw定义的数据不会被正

【汇编语言/底层开发】7、更灵活的定位内存地址方法

1.[bx+idata] 通常情况下,我们使用ds和[bx]指定内存中的一个内存单元.而[bx+idata]所表示的是一种更加灵活的方式来定位内存地址,其表示的是段地址为DS,偏移地址为(bx)+idata的内存位置.通常idata为一个常量,表示一个固定的地址偏移量.如下面几条指令实际上是等价的: mov ax, [bx+200] mov ax, 200[bx] mov ax, [bx].200 其中值得注意的是200[bx]这种方法.通常在给定的数据段中,ds的值通常在程序开始时确定,中间不

【汇编语言/底层开发】10、CALL和RET指令

CALL和RET指令常常用来实现子程序的设计.这两个指令同jmp.loop.jcxz等指令同属于转移指令. 1.ret和retf 转移指令的主要功能就是修改CS和IP或者只修改IP的内容.其中ret利用栈中的数据修改IP的内容,从而实现近转移:而retf则通过使用栈中的数据同时修改CS和IP的值,实现远转移. ret指令的作用相当于: pop IP retf指令的作用相当于: pop IP pop CS ret和retf指令同程序的栈息息相关.通常情况下可以使用默认的栈空间,另外还可以自己定义一

【汇编语言/底层开发】4、使用masm编译、链接汇编源文件

0.准备工作: 由于现在我们的操作系统通常都是win7或者win8,所以要运行masm需要做一些准备工作.这里只简单描述一下过程,详细的请搜索这篇文章<Win7(64位)下使用MASM和DEBUG方法>. 首先创建一个目录,这里假设为e:\asm,并且这个目录里要包含下图中的几个文件: 安装dosbox,执行:mount c: e:asm.完成后,切换到C:目录,即到达我们建立的这个e:\asm目录下. 1.编辑汇编代码: 新建一个文本文件,文件名修改为31.asm,文件内容输入以下汇编代码: