zoukankan      html  css  js  c++  java
  • 汇编语言基础之一 CPU架构和寄存器种类简介

    Intel x86 架构

    Pentium i-386 是一种32-bit CISC (复杂指令计算机) 处理器, 然而APLHA 是基于RISC的(精简指令计算机). 这里不讨论十六位的代码,但是原则都差不多。

    处理器有许多通用寄存器。寄存器是特殊用处的存储位置,他们在微处理器自身之中。访问寄存器比访问其他种类的存储器都要快的多得多。有些寄存器是通用的,而有些是具有特殊用处的。

    通用寄存器被用来存放计算用的数值,并且存储内部的计算结果。寄存器总的说来操纵的是byte, word,或者是DWORD。

    标志位寄存器是仅仅用来操纵bit的寄存器。任何指令都会根据计算的结果影响到标志位寄存器。比如说,经过一个减法操作,如果结果是0,那么zero flag就会被设置,如果不是0,其值会被清掉。

    汇编指令可以有0个,1个,2个操作数。操作数可以使立即数,寄存器中的值,或者是一个指向内存中某个地址的指针。大致上说,Intel汇编语言的语法如下:

    Prefix Instruction [operand 1],[operand 2] ; comment

    其中

    Prefix

    - An address label or instruction modifier

    前缀。标识地址或者操作修改符

    Instruction

    - Instruction being executed

    指令名

    Operand 1

    - Typically the destination operand, but it can be the source operand (one argument instruction), or it can be both the source and destination operands (INC instruction)

    操作数1.一般来说,这个操作数是目的操作数。

    Operand 2

    - Source operand for two argument instructions

    操作数2

    所以,对于MOV EAX,[12345678]指令来说,源操作数是在地址12345678中,而目的操作数是EAX寄存器。这个指令会降存储在12345678中的值,拷贝到EAX寄存器中。

    Intel CPU的寄存器

    Intel386以上的处理器包含一系列的32位寄存器。i386家族的处理器被看作是non-orthogonal的,意思是寄存器和指令集不能完全互换。也就是说,有些指令只能用在特定的寄存器上。比如说,IN和OUT指令是硬件固定的只能用在累加器(EAX)寄存器上,ECX被用来做循环的计数器,EDI和ESI被用来做索引指令和字符串指令。另外的寻址模式只能被用在特定寄存器上。

    i-386家族有六个通用寄存器,EAX, EBX, ECX, EDX, EDI, ESI. 每一个寄存器都是用字母E开头,代表Extended,意思是扩展到了32位,而不是十六位。

    使用方式

    AL

    lower 8 bits of the EAX register

    EAX的低八位

    AH

    high order byte of lower order word of the EAX register

    EAX的高八位

    AX

    lower 16 bits of the EAX register

    EAX的低十六位

    EAX

    the full 32 bits of the register

    整个EAX寄存器

    EBX,ECX和EDX的方式一样。

    注意,ESI和EDI是不能用在byte级上使用的。

    寄存器的种类

    通用寄存器

    1. EAX被用作累加器。它是寄存器中被使用的最多的,而且用来保存许多指令的结果。通常编译过的代码只用EAX寄存器来存放返回值。

    2. ECX被用作计数器。

    3. EBX和EDX是通用寄存器,一般被用来做为指针来进行内存寻址,或者被用来做算术操作,逻辑操作的操作数,和保存指令的运行结果。EAX,ECX也可以像EBX和EDX这样用。

    索引寄存器

    EDI,ESI是专门用来indexing的通用寄存器。字符串操作使用EDI作为目的指针,ESI作为源指针。所以,如果要拷贝一块内存从一个地方到另一个,ESI应该被作为源块,EDI作为目的块。ECX应该加载需要拷贝的字节数,方向标志位(direction flag)会被设置为增加或减少,然后REP MOVS命令来拷贝字节。

    栈寄存器

    ESP和EBP主要是用来操纵控制站的。ESP是栈顶指针,用来指向当前栈顶的位置。EBP寄存器对于一个给定的routine(函数),被用来指向栈frame,也就是栈底。在routine(函数)的入口,EBP寄存器一般会先存储到栈上(将EBP压栈),然后设置EBP为当前栈的栈顶指针(ESP)。EBP被用来引用参数或者局部变量。局部变量的引用可以通过EBP,[EBP-4],[EBP-8]等等方式获得。参数也可以通过EBP获得,比如[EBP+8]。一般局部变量在EBP负的位移上,而函数的参数在EBP正的位移上。

    注意,ESP指向的是栈中当前有值的地址,也就是说ESP指向的是栈的最顶部的有效字节。结合压栈操作来解释吧。下面表格中的操作时等效的。

    push 0x1234H;

    ESP <- ESP – 4 ; 减小栈指针的位置

    SS:[ESP] <- 0x1234H ; 将操作数拷贝到栈顶之中

    下面的代码很具有参考价值

    void SomeProcedure (int anArgument)
    {
      int aVariable;
      aVariable = anArgument;
    }
    
    SomeProcedure:  PUSH    EBP             ;save original value of EBP on stack
                    MOV     EBP, ESP        ;store top of stack address in EBP
                    SUB     ESP, 4          ;allocate space for aVariable on stack
    
                    MOV     EAX, [EBP+8]    ;fetch anArgument into EAX, which is
                                            ;8 bytes below the stored top of stack
                    MOV     [EBP-4], EAX    ;store EAX into aVariable, which is
                                            ;4 bytes above the stored top of stack
    
                    MOV     ESP, EBP        ;free space allocated for aVariable
                    POP     EBP             ;restore original value of EBP
                    RET                     ;return to the caller

    标志位寄存器

    由一系列的单个bit位组成。许多指令修改这些二进制位来描述指令的结果。这些标志位可以被条件跳转jmp语句来使用。

    详细的信息请看下表

    Intel x86 FLAGS Register
    Bit # Abbreviation Description Category[1]
    FLAGS
    0 CF Carry flag S
    1 1 Reserved  
    2 PF Parity flag S
    3 0 Reserved  
    4 AF Adjust flag S
    5 0 Reserved  
    6 ZF Zero flag S
    7 SF Sign flag S
    8 TF Trap flag (single step) X
    9 IF Interrupt enable flag X
    10 DF Direction flag C
    11 OF Overflow flag S
    12, 13 IOPL I/O privilege level (286+ only) X
    14 NT Nested task flag (286+ only) X
    15 0 Reserved  
    EFLAGS
    16 RF Resume flag (386+ only) X
    17 VM Virtual 8086 mode flag (386+ only) X
    18 AC Alignment check (486SX+ only) X
    19 VIF Virtual interrupt flag (Pentium+) X
    20 VIP Virtual interrupt pending (Pentium+) X
    21 ID Identification (Pentium+) X
    22 0 Reserved  
    23 0 Reserved  
    24 0 Reserved  
    25 0 Reserved  
    26 0 Reserved  
    27 0 Reserved  
    28 0 Reserved  
    29 0 Reserved  
    30 0 Reserved  
    31 0 Reserved  
    RFLAGS
    32-63 0 Reserved  

    表注:

    S: Status flag
    C: Control flag
    X: System flag

    特殊目的寄存器

    EIP是指令指针,它指向下一条将要被执行的指令。EIP会被指令RET,RETI,JMP,CALL和INT改变。这个寄存器可能是CPU中最重要的寄存器了,因为他指导着CPU下一条该执行的指令。

    段寄存器

    在32位系统中,段寄存器通常不会被修改或者显式的使用。Win32使用平面内存寻址模式。这样的原因请看文章《Windows背景知识之一》中,《Windows的内存安排》一段的描述。

    额外的寄存器

    Intel家族中还有一些其他的寄存器,但是它们并不适用于用户态的debugging。简单列出他们如下:

    Protected Mode Registers

    Control Registers

    Debug and Test Registers

    Floating Point Unit Register Set

    MMX Registers

    SIMD Floating Point Registers

    练习

    1. EAX寄存器主要是做什么用的?

    答:EAX被用作累加器。它是寄存器中被使用的最多的,而且用来保存许多指令的结果。通常编译过的代码只用EAX寄存器来存放返回值。

    2. ECX寄存器主要是做什么用的?

    答:计数器

    帮助记忆的小窍门

    寄存器 全称 说明
    EAX Extended Accumulator X 累加寄存器。A代表Accumulator
    ECX Extended Counting X 计数寄存器。C代表counting
    EDI Extended Destination Indexing 目的索引寄存器。D代表destnation,I代表Indexing
    ESI Extended Source Indexing 源索引寄存器。S代表Source,I代表Indexing
    ESP Extended Stack Pointer 栈指针寄存器。S代表Stack
    EBP Extended (Stack) Base Pointer 栈基指针寄存器。B代表Base
    EIP Extended Instructions Pointer 指令寄存器。I代表Instruction
  • 相关阅读:
    优雅的windowsC++项目的配置
    C++实现编码转换
    C++读取配置文件
    完全依赖QML实现播放器
    记一次和“N+1”的擦肩而过
    FFmpeg4.0笔记:采集系统声音
    FFmpeg4.0笔记:采集桌面
    FFmpeg4.0笔记:封装ffmpeg的解封装功能类CDemux
    SDL2:封装媒体显示播放Csdl2
    FFmpeg4.0笔记:封装ffmpeg的音频重采样功能类CSwr
  • 原文地址:https://www.cnblogs.com/awpatp/p/1593248.html
Copyright © 2011-2022 走看看