汇编学习笔记基础指令注解

汇编笔记


寄存器register

​ 学习汇编语言,首先必须了解两个知识点:寄存器和内存模型。

​ 先来看寄存器。CPU 本身只负责运算,不负责储存数据。数据一般都储存在内存之中,CPU 要用的时候就去内存读写数据。但是,CPU 的运算速度远高于内存的读写速度,为了避免被拖慢,CPU 都自带一级缓存和二级缓存。基本上,CPU 缓存可以看作是读写速度较快的内存。

​ 但是,CPU 缓存还是不够快,另外数据在缓存里面的地址是不固定的,CPU 每次读写都要寻址也会拖慢速度。因此,除了缓存之外,CPU 还自带了寄存器(register),用来储存最常用的数据。也就是说,那些最频繁读写的数据(比如循环变量),都会放在寄存器里面,CPU 优先读写寄存器,再由寄存器跟内存交换数据。


内存模型:Heap

  • 程序运行过程中,对于动态的内存占用请求(比如新建对象,或者使用malloc命令),系统就会从预先分配好的那段内存之中,划出一部分给用户,具体规则是从起始地址开始划分(实际上,起始地址会有一段静态数据,这里忽略)。举例来说,用户要求得到10个字节内存,那么从起始地址0x1000开始给他分配,一直分配到地址0x100A,如果再要求得到22个字节,那么就分配到0x1020

  • 这种因为用户主动请求而划分出来的内存区域,叫做 Heap(堆)。它由起始地址开始,从低位(地址)向高位(地址)增长\(Heap\) 的一个重要特点就是不会自动消失,必须手动释放,或者由垃圾回收机制来回收

img


内存模型: Stack

  • 除了 Heap 以外,其他的内存占用叫做 Stack(栈)。简单说,Stack 是由于函数运行而临时占用的内存区域

  • 系统开始执行main函数时,会为它在内存里面建立一个帧(frame),所有main的内部变量(比如ab)都保存在这个帧里面。main函数执行结束后,该帧就会被回收,释放所有的内部变量,不再占用空间。

  • 在函数内部在调用一个函数process()的时候,系统也会为该函数再新建一个帧,一般来说调用栈有多少层,就有多少帧.

  • 当函数运行结束之后,它的帧会被回收,系统回到函数中断执行的地方继续执行上一个帧的流程.通过这个机制,可实现函数的层层调用,且每一层函数都可以使用自己的本地变量

  • Stack是由内存区域的结束地址开始分配,从高位到地位分配

img


CPU指令

使用 g++ file.cpp -S out.s或者gcc file.cpp -S out.s,可用C/C++生成相应的汇编代码

#include<stdio.h>
void hello()
{
    int a=1,b=2;
    a=a+b;
    printf("hello world\n");
}
int main()
{
    int a=1,b=2;
    a=a+b;
    hello() ;

    return 0;
}
.LC0:
        .string "hello world"
hello():
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     DWORD PTR [rbp-4], 1
        mov     DWORD PTR [rbp-8], 2
        mov     eax, DWORD PTR [rbp-8]
        add     DWORD PTR [rbp-4], eax
        mov     edi, OFFSET FLAT:.LC0
        call    puts
        nop
        leave
        ret
main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     DWORD PTR [rbp-4], 1
        mov     DWORD PTR [rbp-8], 2
        mov     eax, DWORD PTR [rbp-8]
        add     DWORD PTR [rbp-4], eax
        call    hello()
        mov     eax, 0
        leave
        ret

push 指令

	push	rbp

pushCPU指令,rbp是该指令的算子.一个CPU指令可以有0到多个算子


寄存器

IA-32体系结构中有10个32位和6个16位处理器寄存器.寄存器分三类:

  • 通用寄存器

    • 数据寄存器

    • 指针寄存器

    • 索引寄存器

  • 控制寄存器

  • 段寄存器


指令系统

80x86寻址方式
  • 寻址:寻找操作数的地址.

  • 寻址方式:寻找操作数的方式

80x86指令格式
  • 指令助记符 +操作数1,+操作数2,+操作数3
  • 指令的操作数个数可以是0,1,2,3个
如何确定偏移地址的值
  • 与数据有关的十种方式,
    1. 立即寻址
    2. 寄存器寻址
    3. 直接寻址
    4. 寄存器间接寻址
    5. 寄存器相对寻址
    6. 基址变址寻址
    7. 相对基址变址寻址
    8. 比例变址寻址
    9. 基址比例变址寻址
    10. 相对基址比例变址寻址
  • 与转移地址有关的4种寻址方式
    1. 段内直接寻址
    2. 段内间接寻址
    3. 段间直接寻址
    4. 段间间接寻址

寻址方式

立即寻址方式

MOV AX, 5
MOV AX, 05H

把十六进制数05H 移动到通用寄存器AX

寄存器寻址方式(无EA)

  • 指令所要的操作数已存储在寄存器中或者把目标数存入寄存器
MOV AX , BX
  • 指令中可以引用的寄存器及其符号名称:

8位寄存器 AH、AL、BH、BL、CH、CL、DH、DL
8位寄存器 AX、BX、CX、DX、SI、DI、SP、BP和段寄存器等
8位寄存器 EAX、EBX、ECX、EDX、ESI、EDI、ESP、EBP。
  • DST 和SRC的字长一致

  • CS不能用MOV指令改变

直接寻址方式

  • 指令所要的操作数存放在内存中,在指令中直接给出该操作数的有效地址

  • 物理地址=\((DS)\times16d+EA\)

    • MOV AX , [2000H]

    • MOV AX, VALUE

    • MOV AX , [VALUE]

  • 物理地址=\((ES)\times16d+EA\)

    • MOV AX , ES:[2000H]

    • MOV AX, ES:VALUE

    • MOV AX , ES:[VALUE]

    • 在通常情况下,操作数存放在数据段中,所以,其物理地址将有数据段寄存器DS和指令中的有效地址直接形成但如果使用段超越前缀,那么操作数可存放在其他段中.如:

      MOV ES:[1000H],	AX
      
    • 立即寻址:1234H

    • 直接寻址;[1234H]

寄存器间接寻址方式→EA基址/变址

  • MOV AX,[BX]或MOV AX,ES:[BX]

寄存器相对寻址方式→EA=基址/变址+位移量

  • MOV AX,COUNT[SI]MOV AX,3000H[SI]

  • MOV AX,[COUNT+SI]MOV AX,[3000H+SI]

  • MOV AX,ES:COUNT[SI]MOV AX,ES:[COUNT+SI]

  • 操作数在存储器中,其有效地址是一个基址寄存器(BXBP)或变址寄存器(SIDI的内容和指令中的8位/16位偏移量之和

基址变址寻址方式→EA=基址+变址

  • 操作数在存储器中,其有效地址是一个基址寄存器(BX、BP)和一个变址寄存器(SIDI)的内容之和

    • MOV AX,[BX][SI]MOV AX,[BX+SI]
    • MOV AX,ES:[BX][SI]MOV AX,ES:[BX+SI]

相对基址变址寻址方式→EA=基址+变址+位移量

  • MOV AX,COUNT[BX][SI] MOV AX,-46H[BX][SI]
  • MOV AX,COUNT[BX+SI] MOV AX,0246H[BX+SI]
  • MOV AX,[COUNT+BX+SI]MOV AX,[-56H+BX+SI]
  • MOV AX,ES:COUNT[BX][SI]MOV AX,ES:[0246H+BX+SI]

相对比例变址寻址→EA=变址×比例因子+位移量

  • MOV EBX,[EAX][EDX*8]MOV EBX,

  • [EAX+EDX\*8]MOV EBX,[ESP][EAX*2]

  • MOV EAX,TABLE[EBP][EDI*4]MOV EAX,[TABLE+EBP+EDI\*4]

​ 8位/16位/32位的位移量

注意1:比例因子只能与32位变址寄存器:EAX、EBX、ECX、EDX、EBP、ESI、

EDI联用;且比例因子只能为1、2、4或8;

注意2: 8)、9)、10)只能是32位寻址,没有16位寻址;

基址比例变址寻址→EA=基址+变址×比例因子

相对基址比例变址寻址→EA=基址+变址×比例因子+位移

上一篇:植物明星大乱斗1-gameScene.h


下一篇:ELK日志收集之logstash部署 采集nginx/tomcat方案Filebeat + Logstash + ES + Kibana