汇编第二课:寄存器
CPU的构成:运算器,控制器,寄存器。
- 运算器:信息处理
- 控制器:控制各个器件工作
- 寄存器:信息储存
- 内部总线连接各器件,在它们之间进行信息传递
这些东西经常听经常看,我是这么想的,总之是要熟练的
通用寄存器
不同的cpu,寄存器的个数,结构是不同的,下文以8086cpu为例,虽说年代久远,但可以尝试转化思想考虑如今的cpu。
存放一般性的数据的寄存器称为通用寄存器,8086cpu中为AX,BX,CX,DX。(此处不区分大小写,但某些情况下是区分大小写的,比如其他架构,或者是特定条件下)
8086cpu中的寄存器都是16位的

8086上一代为8位寄存器,为了适配,(以AX为例)AX分为AH和AL(高位和低位)

然后储存数据很明显了,可以以二进制形式看,也可以以十六进制看,此处不多赘述进制转化,看多了就熟练了。
字在寄存器的储存
- 字节记为byte,1字节=8位
- 字记为word,1字由2字节构成,分为高位字节和低位字节
8是个很神奇的数字,一个内存单元为8位,cpu寄存器储存n个八位的数据,计算机大多数据都是n个8位数据构成的。由此也可见十六进制的奥妙,比如如果说AX中存放4D6F,就可以很直观地知道AX是16位,也就是两个八位数据构成。
十六进制:hexadecimal
二进制:binary
所以二进制后面跟B,十六进制后面跟H
汇编指令
目前用不到太多,不过需要提醒的是可以将数据送入AX,也可以单独送入AH或者AL。
mov ax,4096
mov ax,1000H
mov ah,16
mov ax,1000000000000B
不同的将4096送入AX的方式。
如果数据超出,则有对应的报错或者处理,此处暂时不需考虑。
add ax,1 #ax加1
add ax,bx #寄存器ax和bx的值相加,然后存入ax中,此处可见从右向左的思想
至于计算题,我的建议是直接上计算器
此处引用王爽老师书中经典的一道题
用mov和add计算2的四次,最多四条指令
mov ax,2
add ax,ax
add ax,ax
add ax,ax
物理地址
CPU访问内存单元时,要给出内存单元的地址。所以内存单元构成的地址是一个一维线性空间,每个内存单元有唯一的地址,这个唯一的地址称为物理地址。
CPU通过地址总线送入存储器的,必须是一个内存单元的物理地址,而该地址在CPU内部形成,下面我们看8086CPU如何形成物理地址,不同CPU形成方式可能不同
16位CPU
简单来说,满足一下条件,就是16位CPU,其他cpu可以类比
运算器一次最多处理16位数据
寄存器的最大宽度为16位
寄存器和运算器之间的通路为16位
8086CPU给出物理地址的方式
8086cpu地址总线宽度为20位,寻址能力为1MB,但它是16位CPU,一次性处理,运算,储存的地址最大位16位。那么很明显,如果只用一个寄存器储存地址,简单地将地址发出,那么寻址能力变成了64KB。
插个题外话,16位cpu装20位地址总线,原因有很多,其中一个是当时市场上还有8位cpu,16位cpu还能兼容8位cpu的东西,岂不美哉,而且通过下面的方式可以提升寻址能力,从64KB到1MB,也是很有经济效益的。
不多说废话了,
物理地址=基础地址+偏移地址=段地址✖️16+偏移地址
相当于先给你参考系,再给你相对于该参考系的位置。
从数学的角度看,20位数据相当于5位16进制数字,16位数据相当于4位16进制数字,十六进制数字×16,该数字向左进一位,类比十进制数字×10,该十进制数字向左进一位。
现在我们能用两个16位数据表示一个任意20位数据。此处就是非常非常简单的小学数学问题,如何用两个4位数表示一个5位数,只不过是从16进制的角度考虑。
eg:12345H = 1234H×16+5H
段的概念
实际上内存没有分段,只是CPU内部以分段的形式管理内存。
比如10000H到100FFH,段地址位1000H,段大小为100H;10000H到1FFFFH也可以视作一段,段地址也是1000H,段大小为10000H,也就是2^16,也可以称段长度为64KB。10000H到20000H就不可以视作一段(在8086CPU中),因为偏移不了这么多,
段寄存器
顾名思义,提供段地址的寄存器,8086cpu中有四个
CS:code segment 代码段寄存器
DS:data segment 数据段寄存器
SS:stack segment 堆栈段寄存器
ES:extra segment 附加段寄存器
CS 和 IP
8086cpu中最重要的两个寄存器,IP(Instruction Pointer)指针指令寄存器。
任何时刻设CS内容为M,IP为N,cpu从M×16+N地址开始执行命令。
简单说,内存中有命令,CS和IP告诉cpu执行哪里的命令,执行完一条命令后IP的值会自增,以执行下一条指令,增加值为目前命令所占内存单元的数量。(结合下图思考,更多过程图可以上网查或者看王爽老师的书)

修改CS和IP的指令
- jmp 1234:5 #修改CS为1234H,IP为5H
- jmp ax #相当于mov ip ax,但“mov ip ax”是不行的
此处说明一下,IP自增是发生在执行命令之前的,还是比较重要的,当涉及指令是jmp时。
代码段
顾名思义,存放要执行的代码的一段内存
eg:
mov ax,0000 (B8 00 00)
add ax,0123H (05 23 01)
mov bx,ax (8B D8)
jmp bx (FF E3)
这段代码长度为10字节,存放在123B0H~123B9H的一组内存单元中,那么这就是一个代码段,段地址为123BH,长度为10字节

5183

被折叠的 条评论
为什么被折叠?



