不同CPU,寄存器个数结构不同。
对于8086CPU,有AX, BX, CX, DX, SI, DI, SP, BP, IP, CS, SS, DS, ES, FLAG一共14个

寄存器:

通用寄存器:

AX-DX通常用来存放一般性的数据:通用寄存器
image.png

image.png
把寄存器中一个字(如AX=1234)储存在内存中时,先存低位AL=34,再存高位AH=12

段寄存器:

8086CPU有CS, DS, SS, ES作为段寄存器。

寄存器作用:

EAX:(针对操作数和结果数据的)累加器
EBX:(DS段中的数据指针)基址寄存器
ECX:(字符串和循环操作的)计数器
EDX:(I/O指针)数据寄存器
以上4个寄存器主要用于算数运算,常用来保存常量变量的值。Win32 API函数在内部会使用ECX与EDX,调用这些函数时会把寄存器的数据入栈,函数执行完毕之后从栈中恢复。
EBP:(SS段中栈内数据指针)扩展基址指针寄存器, 指向系统栈最上面一个栈帧的底部
ESI:(字符串操作源指针)源变址寄存器
EDI:(字符串操作目标指针)目的变址寄存器
ESP:(SS段中的栈指针)栈指针寄存器
以上4个主要用作保存内存地址的指针。
CS:Code Segment,代码段寄存器
SS:Stack Segment,栈段寄存器
DS:Data Segment,数据段寄存器
ES:Extra Segment,附加(数据)段寄存器
FS, GS:都是Data Segment

地址:

8086CPU中,地址由段地址和偏移地址组成,用地址加法器得到对应的地址,DS寄存器通常用来存放要访问数据的短地址
e.g.设DS=1000,可以这样写:mov al, [0] 把DS:0即1000:0即10000中的数据读入al中。其中[0]为偏移地址。

CS:IP在任意时刻指向CPU当前要读取指令的地址。CS:代码段寄存器,IP:指令指针寄存器。
notice:

  • 00FF:0010 = 00100 = 0001:0000

内存单元:

内存单元是字节单元,[…]表示一个内存单元,其中的地址表示内存单元的偏移地址,所以一个字用两个内存单元储存,N地址字单元储存1234H时,N储存34H,N+1储存12H。
在8086CPU中,只有bx, si, di, bp可以用在“[…]”中进行内存单元的寻址。
在[…]中,这4个寄存器可以单个出现,或只能以4种组合出现:bx和si,bx和di,bp和si,bp和di,如以下指令是正确的:

  1. mov ax, [bx]
  2. mov ax, [si]
  3. mov ax, [di]
  4. mov ax, [bp]
  5. mov ax, [bx + si]
  6. mov ax, [bp + di]
  7. mov ax, [bx + si + idata]
  8. mov ax, [bp + di + idata]

栈:

常用指令:pushpop可以对寄存器,内存单元(以字为单位),寄存器进行操作
执行push 寄存器,CPU先使SP=SP-2,再把寄存器数据高位和低位先后送入栈,pop 寄存器把数据(16位)低位和高位先后存入寄存器。

比如把10000H~1000FH当作栈,则

  1. mov ax, 01234
  2. push ax

使得内存中结构为

1000EH 34
1000FH 12

任意时刻地址SS:SP指向栈顶(此时为1000EH),pop时,SP自动加2,push时减2
(这是反着来的,有点违背直觉)

一个有意思的问题:

如果将1000H~1FFFFH当作栈段,初始状态栈为空,此时SS=1000H, SP=?

分析:push使SP-2,而因为在CPU中0000H- 2H 得到 FFFEH,因此,SP = 0H。

此外 ,一直push直到SP=0时,继续压栈,栈顶将会环绕回FFFEH,覆盖原来栈中内容,因此一个栈段容量最大为64KB。

栈顶超界:

SS:SP并不保证不超出栈空间,pushpop使超出的内存空间可能会引发错误。
pushpop执行时只能修改SP,也就是说,栈顶变化范围最大为:0~FFFFH。

定义段地址用途:

数据段:

将其段地址放在DS中

代码段:

将段中第一条指令的偏移地址放在IP中

栈段:

把段地址放在SS中,栈顶单元偏移地址放在SP中

段本身没有区别,决定其用途的是几个特殊寄存器(CS、IP、SS、SP、DS)储存的地址的指向。

其他:

  1. Debug的T命令在执行修改寄存器SS的指令时,下一条指令也紧接着被执行。
  2. […]表示一个内存单元时,段地址默认在DS中,单元的长度(类型)由具体指令中其他操作对象(比如寄存器)决定。e.g. mov ax, [0]时[0]代表的是一个长度为2字节的内存单元,mov al, [0]为一个字节的内存单元。