zoukankan      html  css  js  c++  java
  • X86汇编语言中的registers相关

    0、写在前面

    本文中总结于王爽老师的汇编语言,建议有兴趣的都买一本,以支持王爽老师的辛勤付出。再者,这本书写的确实很nice。


    8086CPU共有14个registers:AX, BX, CX, DX, SI, DI, SP, BP, IP, CS, SS, DS, ES, PSW, 所有寄存器都是16位的。

    【1】通用寄存器: AX, BX, CX, DX

    通常用于存放一般性的数据;

    【2】CS和IP (code segment and instruction pointer) - 代码段寄存器和指令指针寄存器

    CPU从何处执行是由寄存器决定的, 设CS的value = M, IP的value = N , CPU将从M*16 + N 内存单元开始执行;(因为CPU的地址加法器采用 物理地址 = 段地址*16 + 偏移地址 来表示物理地址)
    Attention: jmp 可以修改CS和IP的值;

    【3】DS(data segment register) - 数据段寄存器

    通常用来存放要访问数据的段地址;

    mov bx,1000h
    mov ds,bx
    mov al,[0] 
    

    将1000:0 内存单元中的 数据copy到 al

    【4】[bx]

    bx用于存放偏移地址EA (effective addr), 段基址在ds中的内存单元;
    如mov [bx] ,ax
    将ax中的内容copy到 ds:bx (ds*16+bx)内存单元中。

    Attention:

    A1) EA-effective address 有效地址==偏移地址;

    A2) SA-segment address 段基址;

    A3) debug 和 汇编编译器masm对指令的不同处理

    对于mob bl,[1] ; mov cl,[2] ; debug将[1] 解释为一个内存单元 即将[idata]解释为[idata]内存单元的偏移地址,段基地址在ds中,而编译器将[1]解释为1, 即将[idata]解释为idata立即数了;

    【5】bx, si , di , bp

    5.1)只有这4个registers 可以用在[…]中来进行内存单元寻址;

    mov ax, [bp + di ]

    5.2)在[…]中, 这4个registers可以单个出现,或只能以4种组合出现

     bx+si ;
     bx+di ;
     bp+si ;
     bp + di;
    

    5.3)只要在[…]中使用寄存器bp, 若指令中没有显性给出段地址,段地址就默认在ss中。

    mov ax,[bp+si+idata] (基址变址相对寻址)

    【6】指令处理的数据在什么地方

    6.1) 立即数, 数据包含在指令中;

    6.2) 寄存器,数据包含在register中

    6.3) 段地址(SA)和偏移地址中(EA)

    mov ax,[bx+si+8] 段地址默认在ds中;
    mov ax,[bp+si + 8] 段地址默认在ss中;
    

    当然你也可以显性指定,如

    mov ax,es:[bx]
    

    6.4) 寻址方式如下:

    这里写图片描述

    【7】指令要处理的数据有多长

    mov word ptr ds:[0],1 ; word ptr指明了访问的内存单元是一个字单元
    mov byteptr ds:[0],1 ; byte ptr指明了访问的内存单元是一字节字单元

    【8】CPU中的栈

    任意时刻, SS:SP指向栈顶元素。push和pop指令时,CPU从ss和sp中得到栈顶元素;

    push ax 分为两步:

    • 8.1) sp = sp - 2 , SS:SP指向当前栈顶前面的单元;
    • 8.2) 将ax内容送到ss:sp 指向的内存单元处;
      入栈时栈顶由高地址向低地址增长。(先送字数据的低字节,后送 高字节)

    【9】pushf和popf (PSW)

    pushf和popf的功能是向标志寄存器的压栈和从标志寄存器出栈;

    什么是标志寄存器, 其中存储的信息就是程序状态字PSW(program status word)
    这里写图片描述
    cf==carry flag (进位标志) 前一条指令执行结果产生的进位
    pf==parity flag (奇偶标志位)前一条指令执行结果 1 的个数是否为偶数,偶数为1,否则为0;
    af==
    zf==zero flag(零标志位) 前一条指令执行结果是否为0,为0则zf=1, 否则为0;
    sf=sign flag (符号标志) 如果为负, sf=1,否则为0;
    tf
    if
    df
    of==overflow flag 溢出标志
    这里写图片描述

    其作用:

    • (1)用来存储相关指令的某些执行结果
    • (2)用来为CPU执行相关指令提供行为依据
    • (3)用来控制cpu的相关工作方式

    【10】串传送指令

    movsb, 功能执行movsb指令相当于进行以下几步:

    • (1)(es)16 + (di) = ((ds) 16 + si)
    • (2)
      如果df = 0 (si) = (si) + 1; (di) = (di) + 1;
      如果df = 1 (si) = (si) - 1; (di) = (di) - 1;

    movsw ,根据标志寄存器df位的值,将si和di +2 或 -2

    如我们的需求:

    • (1)传送的原始位置:ds:si
    • (2) 传送的目的位置:es:di
    • (3)传送的长度:cx
    • (4)传送的方向: df

    代码如下:

    mov ax,data
    mov ds,ax
    mov si,0 ; ds:si 指向data:0
    mov es,ax
    mov di,16  ;  es:di 指向data:0010
    mov cx,16   ; cx=16 ,rep循环16次
    cld            ;设置df=0, 
    rep mobsb
    

    Attention:

    cld: 将标志寄存器的df位置0
    std: 将标志寄存器的df位置1

    【11】offset 操作符

    取偏移地址

    assume cs:codesg
    codesg segment
    
    start: mov ax, offset start   ; 相当于mov ax,0
    s:mov ax, offset s ;相当于mov ax,3
    

    【Complementary】 字符串处理指令

    • (1) lodsb、lodsw:把DS:SI指向的存储单元中的数据装入AL或AX,然后根据DF标志增减SI
    • (2) stosb、stosw:把AL或AX中的数据装入ES:DI指向的存储单元,然后根据DF标志增减DI
    • (3) movsb、movsw:把DS:SI指向的存储单元中的数据装入ES:DI指向的存储单元中,然后根据DF标志分别增减SI和DI
    • (4) scasb、scasw:把AL或AX中的数据与ES:DI指向的存储单元中的数据相减,影响标志位,然后根据DF标志分别增减SI和DI
    • (5) cmpsb、cmpsw:把DS:SI指向的存储单元中的数据与ES:DI指向的存储单元中的数据相减,影响标志位,然后根据DF标志分别增减SI和DI
    • (6) rep:重复其后的串操作指令。重复前先判断CX是否为0,为0就结束重复,否则CX减1,重复其后的串操作指令。主要用在MOVS和STOS前。一般不用在LODS前。

    Attention

    上述指令涉及的寄存器:段寄存器DS和ES、变址寄存器SI和DI、累加器AX、计数器CX
    涉及的标志位:DF、AF、CF、OF、PF、SF、ZF

    版权声明:本文为博主原创文章,未经博主允许不得转载。

  • 相关阅读:
    智能指针之第二印象
    网易实习笔试真题C/C++
    map,hash_map和unordered_map 实现比较
    斐波那契堆(一)之 图文解析 和 C语言的实现
    二项堆(一)之 图文解析 和 C语言的实现
    寻找最小的k个数
    P、NP、NP-Complete、NP-hard问题
    网易有道笔试:求连通图的割点(关节点)
    块设备的读流程分析
    不相交集(The Disjoint Set ADT)
  • 原文地址:https://www.cnblogs.com/pacoson/p/4893178.html
Copyright © 2011-2022 走看看