汇编语言之寄存器总结

      现在的电脑已经从以前的32位变为现在的64位,但是CPU的老祖宗8086,我们依然不能忘记呀,所以趁着有时间今天就早期8086总结一下各种寄存器的相关属性。


早期的8086CPU总共有14个寄存器:

即 AX,BX,CX,DX,SP,BP,SI,DI,IP,FLAG,CS,DS,SS,ES 共 14 个。

大致可以分为三大类():

1. 通用寄存器:

  • AX,BX,CX,DX 称作为数据寄存器:

AX (Accumulator):累加寄存器,也称之为累加器;
BX (Base):基地址寄存器;
CX (Count):计数器寄存器;
DX (Data):数据寄存器;

  • SP 和 BP 又称作为指针寄存器:

SP (Stack Pointer):堆栈指针寄存器;
BP (Base Pointer):基指针寄存器;

  • SI 和 DI 又称作为变址寄存器:

SI (Source Index):源变址寄存器;
DI (Destination Index):目的变址寄存器;

2. 控制寄存器:

  • IP (Instruction Pointer):指令指针寄存器;
  • FLAG:标志寄存器;

3. 段寄存器:

  • CS (Code Segment):代码段寄存器;
  • DS (Data Segment):数据段寄存器;
  • SS (Stack Segment):堆栈段寄存器;
  • ES (Extra Segment):附加段寄存器;

以上是常见的寄存器分类;其中值得注意的每个寄存器的都是16位的(即dword双字节的),而除了4个数据寄存器之外的寄存器均不可分为两个8位的寄存器使用需要重点注意

我们就这几个寄存器简单的总结一下各自的作用:(注意在debug模式下数字默认是16进制的,而在记事本中编辑汇编代码是10进制的,需要在其后加上h表示16进制)

以下代码均在debug模式下输入,默认为16进制,不用输入h

1. 4个数据寄存器是可拆分的

例如 AX可分为AH(高位寄存器)和AL(低位寄存器),即:在负值的时候可分开赋值

  mov al,1213:[0];这样的话CPU就会从段地址为1213,偏移地址为0的位置取一个字节长度的机器码,存入ax的低位,这里假设该机器码为A8
  mov ah,0;这样将高位设置为0
  ;然后进入debug进行单步调试,你会发现ax的值变为00A8

2. CS/IP寄存器

CS:IP索引的内存地址即为CPU开始读取代码的起点,之后的一段代码区域,被称为代码片段(code segement),这两个寄存器不能进行赋值操作(mov操作),只能通过jum汇编指令跳转

  jmp 4E6A:0;CPU将跳转到4E6A:0地址执行其中的机器码

除此之外jmp还有其他用法,请参照:JMP指令

3. SS/SP

用于指向栈顶的地址

4. 内存地址索引

一个内存地址可由:

  mov ax,[bx]
  mov ax,[si]
  mov ax,[di]
  ;以上的三个赋值语句,后方的[]中的寄存器所存的值即为偏移地址,而段地址默认存在ds中,即与上代码等效的语句如下:
  mov ax,ds:[bx]
  mov ax,[bp];若使用bp寄存器的值作为偏移地址则默认段地址存在SS中,即:
  mov ax,ss:[bp]
  ;以上的寄存器还可以搭配使用:
  mov ax,[bx+si+200];除了bp和bx,si和di不能同时出现外其他均可自由搭配索引
  ;以下两个语句与上等效,当数字写在[]后时要加.
  mov ax,200[bx+si]
  mov ax,[bx+si].200
  ;当使用idata即立即数(immediate date)若是以字母开头需要在前补个0
  mov ax,[02AE]
  

5. segment(段)

汇编中有以下几个常见的段:

  • 数据段(被存在DS指定的段地址开始的地方)
  • 代码段(被存在CS指定的段地址开始的地方)
  • 栈段(被存在SS指定的段地址开始的地方)

一般通过assume伪指令把数据段绑定在对应段上

也可以通过如下语句绑定:

  assume cs:code,ds:data,ss:stack;将其寄存器对应段指向各个段
  data segment
  	dw 0123h,0456h,0789h,0123h,0456h,0789h,0123h,0456h
  data ends
  
  stack segment
  	dw 0 ,0, 0, 0, 0, 0, 0;初始化栈段内的数据均为0
  stack ends
  
  code segment 
  start:
  	mov ax,stack;手动使寄存器指向栈段
  	mov ss,ax
  	mov ax,data;手动使寄存器指向数据段段
  	mov ds,ax
  	mov bx,0
  	mov cx,8
  	s:push [bx]
          add bx,2
          loop s
          int 21h
       s0:pop [bx]
       	add bx,2
       loop s0
       mov ax,4c00h
       int 21h;正常中断程序
  code ends
  end start

你可能感兴趣的:(汇编语言)