小白的汇编之路(二)----寄存器

小白的汇编之路(二)----寄存器

前言

CPU是由运算器,控制器,寄存器等部件组成的
对于一个汇编程序员来说,重要的是寄存器,因为汇编程序需要对寄存器进行操作,以达到暂存数据的功能
例如:执行3+4,结果存入寄存器a中(其实并不存在a寄存器,在此只是假设)
先将3存入a寄存器中,再将a寄存器的值与4相加:
mov a,3
add a,4
8086CPU中有14个寄存器,许多寄存器都有其独特的用途

通用寄存器

在CPU中,AX,BX,CX,DX是用来存储一般性数据的,所以被称为通用性寄存器。

值得一提的是,8086的上一代CPU是使用8位寄存器的,
而8086CPU是使用16位寄存器的,为了更好的兼容性,可以对CPU编写的程序稍加修改就能运行在8086CPU上,也就是规定了可以把下面这个16位寄存器分为高低寄存器进行使用
(有一说一,这“图”我画的真难看,不过帅气的你应该看得懂的)
假设该16位寄存器为:AX
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
则其低8位寄存器名为:AL
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
高8为寄存器名为:AH
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 |

相关的赋值问题(高低位字节的赋值)

有了上面的介绍,那么问题来了,怎么赋值?
若寄存器AX中存放的值为:(0110010101101011)
| 0 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 |
假如有这样一条命令:mov ax,16
那么该寄存器会如何变化???
先把16转成二进制~然后寄存器的值就会变成:
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
那如果是:mov al,16 呢???
| 0 | 1 | 1 | 0 | 0 | 1 | 0 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
那如果是mov ax,16 呢???
| 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 0 | 1 | 0 | 1 | 1 |
相信聪明的你已经明白了吧!
没错,mov ax, 16 其实是对整个ax寄存器进行赋值,所以16位都被进行赋值了
而 mov al,16 则是对ax寄存器的低8位进行赋值,而对于高8位,CPU并未收到相关的指令,所以不变
而mov ax,16亦是同样的道理
而与这些相关的赋值问题后面还会遇到,可以暂且不予理会

运算“溢出”

对于al来说,如果执行这样的命令:
mov al,C5H
add al,93H
结果为158H,很明显超出了8位寄存器能表示的范围,那么溢出的部分会去哪?这个后面会涉及到,与标志寄存器(flag)有关

简单的汇编指令

mov al,63H
将63H赋给al寄存器
mov al,ah
将ah寄存器的值赋给al寄存器
add al,63H
将63H与al寄存器的值相加,结果存入al寄存器中
add al,ah
将al寄存器的值与ah寄存器的值相加,结果存入al寄存器中

8086CPU的寻址过程

在这里插入图片描述图片戒子(图片截自百度文库https://wenku.baidu.com/view/5f6425a84b35eefdc9d33347.html?from=search)
上图是CPU的“大概"部件(真实的CPU会更复杂)
当CPU根据给出的物理地址,去取出对应内存单位的值,它是怎么工作的呢?

  1. 首先:CPU将cs和ip寄存器中的值,存入地址加法器中,进行地址的“拼接”处理 (“拼接”处理,其实并不是简单的拼接
    地址加法器采用:物理地址=段地址*16+偏移地址 其中段地址就是程序代码段的起始地址,通常存于cs寄存器中,先暂时这样理解即可
    而偏移地址则是ip寄存器的值 )
  2. 然后将"拼接“的地址传入”输入输出电路“;
  3. 将”输入输出电路“的地址传入地址总线,前往对应的内存地址取值;
  4. 然后将值通过数据总线返回至”输入输出电路“;
  5. 再送至”指令缓冲器“中,并在此时,将ip寄存器的值加上相应的值,以便取到下一条指令; 例如取出来的是B8 23,则ip的值加上2(B8 23 代表两个字节);(若是对ip的值进行修改,可以实现跳转到代码段中的某一句代码,但如今只需了解我们可以通过修改ip的值来实现程序指令的跳转)
  6. 执行”指令缓冲器“内的指令。

注意:地址加法器对cs和ip寄存器内的地址所采取的处理方法是为了能指定更大范围的内存地址。这种处理方法非常重要,后续会有很多基础操作与其相关!!!

代码段

在编程时,我们可以根据需要,将一段内存单元设置为一个段,
例如:
(jmp bx 就是对ip寄存器值操作的相关指令之一,暂且将其理解为用bx寄存器内的值修改ip寄存器的值即可)

mov ax,0000
(对应的指令为:B8 00 00)
add ax,0123H
(05 23 01)
mov bx,ax
(8B D8)
jmp bx
(FF E3)

这样的代码段一共10个字节,也就是说这组代码存于一个长度为10个字节的内存单元中
若要执行这段代码,需让cs寄存器”指向“这段代码的起始地址,也就是第一句代码在内存中的地址。
内存并未被进行分段,而是CPU进行的。
但需要注意,由于CPU的程序段的程序读取是通过ip(也就是偏移地址)进行的,所以一个段的最大长度应该为64KB,因为ip寄存器是16位的,16位二进制的范围是0~216-1,所以段的大小不超过64KB

To be continue~~

发布了10 篇原创文章 · 获赞 3 · 访问量 327

猜你喜欢

转载自blog.csdn.net/weixin_41043607/article/details/103896231