汇编语言基础知识

2023-11-10


文章目录

80386常用寄存器

一、常用寄存器

1.1 通用寄存器

  • EAX:累加寄存器
  • EBX:基址寄存器
  • ECX:计数寄存器
  • EDX:I/O指针–数据寄存器
  • ESI:(字符串操作源指针)源变址寄存器
  • EDI:(字符串操作目的指针)目的变址寄存器、
  • ESP:堆栈指针寄存器,存放对战的栈顶地址,不可做为通用寄存器
  • EBP:基址指针寄存器,表示栈区域的基地址,保存ESP,函数返回时把值返回ESP

1.2 段寄存器

Intel公司决定采用 (段地址<<4)+段偏移 的方式,组合成20位地址。 • 16bit段地址保存在段寄存器中;段偏移也是16bit。 • 通过将段地址左移4bit的方式,将两个16bit地址组合成20bit地址。

1.3 程序状态与控制寄存器

  • EFLAGS,标志寄存器:

    • 存储相关指令的某些执行结果
    • 为CPU执行相关指令提供行为数据
    • 控制CPU的相关工作方式
  • CF:进位标识位:

    • 无符号运算,记录运算结果的最高有效位向更高有效位的进位或借位值
    • 加法,进位则CF=1
    • 减法,借位则CF=1
  • PF:奇偶标志位

    • 结果中1的个数为偶数,则PF=1
    • 结果中1的个数为奇数,则PF=0
  • AF:辅助进位标志位

    • 字操作时,发生低字节向高字节进位或借位,AF=1
    • 字节操作时,低4位向高4位进位或借位时,AF=1
  • ZF:零标志位

    • 结果位0,则ZF=1
  • SF:符号标志位

    • 记录相关指令执行后,其结果为负数,SF=1
  • OF:溢出标志位

    • 发生溢出,则OF=1
  • EIP:指令指针寄存器

    • 保存着CPU下一条将要执行指令的地址
    • EIP自动增加,不能直接修改EIP,可以由JMP、CALL、RET、中断或异常修改

二、常用基本指令

2.1 数据传送指令

  • 将数据、地址或立即数传送到寄存器或存储单元
    • MOV:把源操作数传送到目的操作数
      • MOV EAX,EDX; 寄存器EDX --》EAX的数据传送
      • MOV WORD PTR[BX+DI],2; 16位立即数2送偏移地址为位BX+DI的字单元
    • LEA:将源操作数的有效地址传送到通用寄存器
      • LEA EAX,[EBP-4]; 将SS段中EBP-4所指向的存储单元送入EAX
      • 等价于MOV EAX,EBP-4
    • PUSH:操作数压入栈
      • PUSH EAX; 寄存器EAX的值存入栈顶ESP
    • POP:出栈
      • POP EAX; 栈顶ESP保存的数据取出,赋值给EAX,再将ESP+4

2.2 算术运算指令

  • 加法指令:ADD,INC
  • 减法指令:SUB,DEC
  • 乘法指令:MUL
  • 除法指令:DIV
2.2.1 加法指令
  • ADD :将源操作数和目的操作数相加,结果从到目的操作数
    • ADD EAX,EBX; 将EAX,EBX的值相加,结果送到EAX中
    • ADD指令的执行会影响CF,ZF
  • INC:将目的操作数+1
    • INC EAX:将EAX的值加一
    • 目的操作数可以是通用寄存器,也可以是内存单元
2.2.2 减法指令
  • SUB:将目的操作数减去源操作数,结果送入目的操作数
    • SUB EAX,EBX;计算EAX-EBX的值,结果保存到EAX中
    • SUB 指令执行同样会影响CF,ZF等标志位
  • DEC:将目的操作数减一
    • 同上INC
2.2.3 乘法指令
  • MUL:无符号数乘法指令,将源操作数和目的操作数相乘,结果送入目的操作数
  • IMUL:有符号数乘法指令,将源操作数和累加器中的操作数相乘,结果送入目的操作数
    • MUL,IMUL指令的源操作数为通用寄存器或存储器操作数,目的操作数缺省存放在寄存器(EAX)中
    • MUL EBX;将EAX*EBX的值保存在EAX中
2.2.4 除法指令
  • DIV:无符号数除法指令
  • IDIV:有符号数除法指令
    • DIV、IDIV指令的源操作数为通用寄存器或存储器操作数,目的操作数缺省存放在寄存器(EAX)中
    • DIV EBX;将EBX除以EAX的值保存在EAX中,余数放在EDX中

2.3 逻辑运算和移位指令

2.3.1 逻辑运算指令
  • AND:逻辑与
  • OR:逻辑或
  • XOR:逻辑异或
  • 指令格式: AND(OR/XOR) DEST,SRC
    • 源操作数可以是通用寄存器、存储器操作数或立即数,目的操作数是通用寄存器或存储器操作数
    • AND EAX,EBX;将EAX,EBX按逻辑与,结果存在EAX
  • NOT:逻辑非,按位取反,结果存入目的操作数
    • NOT DEST
2.3.2 移位指令
  • SAL:算术左移
  • SHL:逻辑左移
  • 指令格式:SAL (SHL) DEST,OPR
    • SAL ECX,4; ECX左移4位,结果存在ECX中
    • 说明:SAL、ECX指令功能完全相同,按照操作数 OPRD 的规定的移位位 数对目的操作数进行左移操作,每移一位,最低位补0,最高位移入标志 位 CF 中。左移都是补0。
  • SAR:算术右移,
    • 每移一位, 最低位移入标志位 CF,最高位(符号位)保持不变。相当于对有符号数进行除 2 操作。最高位填充符号位。正数填充0,负数填充1
  • SHR:逻辑右移
    • 每移一位, 最低位移入标志位 CF,最高位补0。
  • 指令格式:SAR DEST,ORPD
2.3.3 循环移位指令
  • ROL:循环左移
  • ROR:循环右移
  • 指令格式:ROL DEST,OPRD

2.4 控制转移指令

2.4.1 无条件转移指令
  • JMP:无条件转移
  • CALL:过程调用,等价于PUSH EIP+4;JMP addr
  • RET:过程返回,从栈中将保存的返回地址取出,跳转到原函数执行,等价于POP EIP
2.4.2 条件转移指令
指令 转移条件 说明
JC $dest CF=1 有进位/借位时转移
JNC $dest CF=1 无进位/借位时转移
JE/JZ $dest ZF=1 相等/等于0时转移
JNE/JNZ $dest ZF=0 不相等/不等于0时转移
JS $dest SF=1 是负数时 转移
JNS $dest SF=0 不是负数时转移
  • 通常条件转移指令会和能改变 EFLAGS 对应位的指令配合使用
  • CMP 指令和 SUB 指令相同,但不会将计算结果保存到目的操作数。因此, CMP EAX, 3 执行之后会修改 EFLAGS 的 ZF 标志位:
    • 如果 EAX – 3 = 0,则 ZF 置为 1
    • 如果 EAX – 3 ≠ 0,则 ZF 置为 0
  • JZ 指令查看 ZF 标志位,如果是 1 ,则跳转到对应位置,否则顺序执行

PLT表和GOT表

1、Linux编译过程

预处理、编译、汇编、链接

1.1 预处理

  • 处理所有宏定义 #define 以及所有的条件预编译指令(#if #ifdef #elif #else #endif)
  • 处理#include预编译指令,将被包含的文件插入到该预编译指令的位置
  • 删除所有注释
  • 添加行号和文件标识,以便编译时产生调试用的行号及编译错误警告行号
  • 保留所有#pragma编译器指令,后续编译过程需要使用

1.2 编译

  • 编译:利用编译程序,将源语言编写的程序转化为目标语言的过程
  • 目标语言就是汇编语言

1.3 汇编

  • 汇编:对汇编语言编写的代码进行处理,生成处理器能够识别的指令,即机器码
  • 生成目标文件

1.4 链接

  • 汇编生成的目标文件 .o 不能直接运行
  • 只有我们自己写的代码转换成了机器码,他需要和系统组件(标准库、动态链接库等)搭起来才能运行
  • 链接LInk是一个打包的过程,将所有二进制形式的目标文件和系统组件组合 成一个可执行文件,完成连接的过程叫 链接器

2、静态编译动态链接

  • 静态编译

  • 在编译时,将生成的目标文件.o 和需要的库文件一起打包到可执行文件中。此使静态库可理解为一组目标文件的集合,即很多目标文件压缩打包后形成的文件。

  • 特点:

    • 程序运行时与函数库无关
    • 资源冗余
    • 在编译时就发生了
  • 动态链接

  • 动态库的程序在程序运行时才会被载入,规避了空间浪费的问题

3、延迟绑定

  • 把对某个函数地址进行重定位的工作,推迟到该函数被第一次调用时再进行
  • ELF使用 PLT 过程链接表 技术实现延迟绑定

3.1 重定向

  • 在程序编译的期间,引用外部函数和变量时,只需要知道其声明和类型。函数的定义以及变量(外部符号)时,只需要知道其生命和类型。函数的定义以及变量的值要到链接甚至执行时才能确定。
  • call read:调用read
    • 在编译时,会充填上一个占位值,使程序能够正确调用read函数,就是重定位
  • 不直接在代码段放置并修改占位值,因为代码段不可修改,真正:在调用外部函数时,首先跳转到PLT表,PLT表中的代码会解析函数的真实地址,并将它充填到GOT表中,此后直接跳转GOT表就可以执行对应的外部函数。

3.2 GOT表

全局偏移表,用于记录在ELF文件中所用到的共享库中符号的真实地址

3.3 PLT表

在真正的实现中,并不直接在代码段放置并修改占位值,因为代码段是不可修改的。真正实现方法是:在调用外部函数时,首先跳转到PLT表,PLT标会解析函数真实地址,并填到GOT表中

过程链接表

4、GOT表的攻击利用

  • GOT表项保存的使外部函数的真实地址

  • 由于GOT表字段需要动态修改,所以它是可写的

    • 修改GOT表字段的值,就可以控制程序流
    • 打印GOT表字段的值,就可以泄露libc地址
  • 库函数指 Linux GNU C 函数库,由 GNU 组织在开发 Linux 时编写。

  • 包括 stdio,ctype,string 等常用库 • 库函数被编译为动态链接库,由各个程序共享。

  • 泄漏 libc 的地址,是完成攻击的重要部分

栈溢出基本原理

1、函数栈调用原理

  • 函数调用栈:是指程序运行时内存一段连续的区域,用来保存函数运行时的状态信息,包括函数参数与局部变量等
  • 栈由高地址向低地址扩展。(相对,堆由低地址向高地址扩展)
  • 函数栈的状态主要涉及三个传感器:
    • ESP:栈顶指针
    • EBP:栈底指针
    • EIP:指向下一条执行的指令(PC)

1.1 参数逆序入栈

  • 将被调用函数的参数逆序压入栈中
    • 64位机首先用寄存器传参,前六个参数被传入RDI,RSI,RDX,RCX,R8,R9,其余参数再压入栈
      在这里插入图片描述

1.2 保存返回地址

  • 将调用函数进行调用之后的下一条指令地址作为返回地址,压入栈中,目的是保存caller的rip信息

在这里插入图片描述

1.3 保存(主调函数的)栈基地址

  • 将调用函数的基地址(ebp的值)压入栈内
  • 将当前栈顶地址传到ebp寄存器内

在这里插入图片描述

1.4 进入函数执行

  • 抬高ESP,为新的函数栈留出空间,保留新函数的临时变量
  • 新函数能使用的空间在ESP到EBP之间,EBP不会移动,保证之前栈中的临时变量不会改变

在这里插入图片描述

1.5 清理(被调函数的)局部变量

(函数返回的过程)

把EXP挪到EBP的位值,之前ESP和EBP之间的变量都作废

在这里插入图片描述

1.6 恢复(主调函数)函数栈

将主调函数的栈基地址从栈中取出,保存到EBP寄存器内,此使栈顶指针ESP指向返回地址

在这里插入图片描述

1.7 恢复EIP,清理参数

  • 再将返回地址从栈内弹出,并存到EIP寄存器内
  • 手动或自动清理参数

在这里插入图片描述

2、栈溢出

  • 缓冲区溢出(buffer overflow),是针对程序设计缺陷,向程序输入缓冲区写入使之溢出的内容(通常是超过缓冲区能保存的最大数据量的数据),从而破坏程序运行、趁着中断之际获取程序乃至系统的控制权。

  • 缓冲区溢出发生在函数栈时,称为栈溢出

  • 漏洞利用的目的是获得控制权(执行任意指令)

  • 控制程序流,让EIP载入攻击指令的地址

    • 如果我们能在函数返回之前,修改Retrun Address的值,就能让EIP跳转到我们指定的位置。比如说,如果我们写入了一段shellcode,并把Return Address的值修改为shellcode的地址,那么函数返回时就会执行shellcode。
  • 利用缓冲区溢出

    • 当上一个栈的变量(如字符串)使用了危险函数(gets等),就会造成溢出。溢出的数据覆盖后续的变量,直至修改Return Address。
    • 如果将Return Address修改为system函数的地址,就会启动新进程执行一条命令。

在这里插入图片描述

在这里插入图片描述

3、ROP技术

  • ROP 返回导向编程,攻击者使用堆栈的控制来在现有程序代码中的子程序中的返回指令之前,立即间接地执行精心挑选的指令或机器指令组。
  • 因为所有执行的指令来自原始程序内的可执行存储器区域,所以这避免了直接代码注入的麻烦,并绕过了用来组织来自用户控制的存储器的指令的执行的大多数安全措施(NX)

3.1 32位

  • 32位架构下,函数的参数保存在栈中
  • 将对应参数布置在栈中即可
  • 返回地址下方是第二次的返回地址

在这里插入图片描述

3.2 64位

  • 64位架构下,函数的前六个参数保存 在RDI,RSI,RDX,RCX,R8和 R9中, 如果还有更多的参数才保存在栈里。
  • 劫持控制流后,必须先将参数设置到寄存器中,再跳转到相应的函数执行
  • 对应上文的利用方法,必须先将字符串“/bin/sh”的地址保存在RDI,再跳转到system执行

在这里插入图片描述

  • 参数布置在RDI

  • 利用特殊的程序片段(gadget)来设置寄存器的值

  • 利用工具 ROPgadget 来寻找可用的程序片段

  • ROPgadget --binary stack1-x64 --only “pop|ret”

格式化字符串漏洞

1、格式化字符串原理

  • 格式化字符串函数可以接受可变数量的参数,并将第一个参数作为格式化字符串,根据其解析之后的参数,通俗的来说,格式化字符串函数就是将计算机内存中表示的数据转化为我们人类可读的字符串格式。
    • printf等

在这里插入图片描述

格式化字符串的基本格式如下:

  • %[parameter] [flags] [fieldwidth] [.precision] [length] type

  • parameter: 指定第几个参数,用n$指定第n个参数

  • fieldwidth:指定输出的最小宽度

  • precision:指定输出的精度(最大宽度)

  • type:转换说明,指明转换的类型

    • %d/%i:转换为有符号数
    • %s:将指定参数作为地址,转换为指向的字符串
  • length:输出的长度

    • 默认4Byte,h表示2Byte,hh表示1Byte
    ???

2、格式化字符串漏洞

  • C语言并未检查格式化字符串和参数的对应关系
    • (printf(“%d %d %d %s”, 123 , 345))
  • 如果用户能控制格式化字符串,就能够实现:
    • 读取内存值:利用%d,%p打印栈中的值,%s获取指定内存地址的值
    • 修改内存值:利用%n实现对指定内存地址的写入
    • 引发程序崩溃:当%s对应的地址不是可读位置,将引发错误
  • 假设我们能够控制栈的内容,在printf的第二个参数的位置设置为puts@got的地址
    • “%2$p”:打印puts@got的内容
    • ”aaaaa%2¥n“:将puts@got的内容修改为5

在这里插入图片描述

  • 在x64架构下,前六个参数保存于寄存器

  • 局部覆盖

    • 将值 0x080485AF 修改为 0x08048437
    • 只需要覆盖低2Byte即可
  • 大端序:高位字节放在内存的低地址,低位字节放在内存的高地址。

  • 小端序:低位字节放在内存的低地址,高位字节放在内存的高地址。

  1. 字符串存放

    • 低地址 高地址
    • iamfsadsad
  2. 整数表示

    • 高位 低位
    • 0x1232BCD
  3. 大端 一般书写
    • 低地址 高地址
    • \x12\x34\xAB\xCD
  4. 小端
    • 低地址 高地址
    • \xCD\xAB\x34\x12

GLIBC HEAP

1、内存分配器

1.1 HEAP

  • LInux提供两个系统调用来分配动态内存:
    • brk():扩充或收缩堆的大小
    • mmap():在内存空间寻找一块区域映射

1.2 内存分配器PTMALLOC2

  • 仅使用这两个函数分配内存,对于应用程序非常不友好
    • 现申请内存块a,再申请b;要想释放b,必须先释放a
  • 内存分配器作为中间层
    • 对应用程序提供接口 malloc/free
    • 使用brk,mmap 系统调用获得内存,并负责管理
    • Linux 使用 ptmalloc2 作为分配器

2、PTMALLOC数据结构

2.1 PTMALLOC 管理概述

  • 我们称malloc申请所得的内存为 chunk 块
    • chunk保存了内存分配器用于管理内存的数据结构
    • chunk有两种状态:使用 (malloc得到), 空闲 (free释放)
    • 空闲chunk不会立即还给操作系统,而被分配器统一管理,存放于bin中
      • 一般相同的chunk组织成为一个双链表,便于索引

2.2 CHUNK结构解析

  • prev_size:物理地址前一chunk的大小
  • size:当前chunk的大小,必须是2*SIZE_SZ的整 数倍,即32位架构下,必须是0x8的倍数;64位架 构下,必须是0x10的倍数。因此,低3bit被空出, 作为标志位:
    • A标志:是否是主分配区(main arena)
    • M标志:是否是mmap()映射区域
    • P标志:物理地址前一chunk(prev chunk)是 否正在被使用
  • prev_size: 物理地址前一chunk的大小
  • fd/bk: (forward, back)
    • fd 指向下一个(非物理相邻)空闲的 chunk
    • bk 指向上一个(非物理相邻)空闲的 chunk
  • fd_nextsize/bk_nextsize: 仅用于large bin
    • fd_nextsize 指向前一个与当前 chunk 大 小不同的第一个空闲块,不包含 bin 的头指 针。
    • bk_nextsize 指向后一个与当前 chunk 大 小不同的第一个空闲块,不包含 bin 的头指针。

2.3 CHUNK的空间复用

  • chunk的空间复用
    • 当chunk处于使用状态时,其 fd/bk 和 fd_nextsize /bk_nextsize 区域都不起作 用,作为用户数据使用;其释放后,该字段 用于bin中的链表管理。
    • chunk 处于使用状态时,其物理地址后 一 chunk 的 prev_size 字段不起作用, 作为前一 chunk 的用户数据字段。

2.4 BINS介绍

  • 用户释放掉的 chunk 不会马上归还给系统,ptmalloc 会统一管理 heap 和 mmap 映射区域中的空闲的 chunk。
  • 当用户再一次请求分配内存时,ptmalloc 分配器会试图在空闲的 chunk 中挑选一块合适的给用户。这样可以避免频繁的系统调用,降低 内存分配的开销。
  • 按照chunk的大小和使用状态,设置4种bin进行管理:
    • fast bin(单链表)
    • small bin(双链表)
    • large bin(双链表)
    • unsorted bin(双链表)
  • bins是一个数组,每个成员都是一个链 表指针,共127*2个成员。
  • 为了方便起见,我们认为只有127个成员, 每个成员是一对双链表指针。

在这里插入图片描述

2.5 堆段的产生和初始化

  • 第一次malloc后,进程会创建堆段 (heap segment)。除了会获得所申请空 间的内存大小,还会获得一个连续的内 存块,称为分配区(arena)
  • 虽然程序可能只是向操作系统申请较小的 内存,操作系统会将一块相当大的空间 (20K)返回给用户程序,交由内存分配器 管理。这样做是为了避免过多地使用系统 调用。
  • 当arena空间不足时,通过brk()来增加堆 空间。同理也可以缩小堆空间。
  • arena的相关信息记录在arena header 中,即右图所示的结构体内。

在这里插入图片描述

2.51 TOP CHUNK

  • topchunk 位于堆地址最高的位置,该chunk不属于任何bin,是特殊的chunk
  • 当调用 malloc 时,分配器会先尝试在 bins中寻找合适的空闲块分配;如果 bins中没有合适的块,则会尝试 从 topchunk中切割出合适的大小,返回给 用户。
  • 当释放一个chunk时,如果它与 topchunk物理地址相邻,则直接并入 topchunk 。

2.6 FAST BIN

大多数程序经常会申请以及释放一些比较小的内存块。如果将一 些较小的 chunk 释放之后发现存在与之相邻的空闲的 chunk 并 将它们进行合并,那么当下一次再次申请相应大小的 chunk 时, 就需要对 chunk 进行分割,这样就大大降低了堆的利用效率。 因为我们把大部分时间花在了合并、分割以及中间检查的过程中。 因此,ptmalloc 中专门设计了 fast bin,对应的变量就是 malloc state 中的 fastbinsY

  • 32B <= fastbin <= 128B
  • 单向链表。(所以只使用fd,废弃bk )
  • free时不复位inuse位!(避免合并)
  • 采用LIFO原则(后被释放的chunk将先 被申请到)
  • fastbin 和 smallbin 的大小有重合,而 fastbin的优先级高于smallbin 。
  • 在这里插入图片描述

2.7 SMALL BIN

  • 32B <= smallbin <= 1008B
  • 循环双向链表。为了简化结点的处理,头部也视为一 个结点
  • free 时inuse位置为 0
  • 采用FIFO原则(先被释放的chunk将先被申请到)
    • 无论是fd指针,还是bk指针,指向的都是chunk header的起始处!
  • 在这里插入图片描述

2.8 UNSORTED BIN

  • unsortedbin 只有一个链表(在 bin 中只占一项),其链表结构组织 方式和 smallbin 相同。
  • unsorted bin 可以视为空闲 chunk 回归其所属 bin 之前的缓冲区。
    • 当一个较大的 chunk (非topchunk)被分割成两半后,如果剩下的部分大于 MINSIZE(=32B),就会被放到 unsorted bin 中。
    • 释放一个不属于 fast bin 的 chunk,并且该 chunk 不和 top chunk 紧邻 时,该 chunk 会被首先放到 unsorted bin 中。
  • 释放一个不属于 fast bin 的 chunk,并且该 chunk 不和 top chunk 紧邻 时,该 chunk 会被首先放到 unsorted bin 中。
  • 在特定时刻,unsortedbin会清空,将相应的chunk放入smallbin与 largebin。

2.9 LARGE BIN

  • smallbin 与 fastbin 中,每个链表chunk大小相同;而 largebin 仅限 定大小在一定范围即可。(范围太大,不便于细分)
  • 循环双向链表,额外增设 fd_nextsize 和 bk_nextsize,用于快速适配。
    • 同一链表内,按照chunk的大小进行排序,size大者靠前
    • 相同size,则先释放者靠前。

3、MALLOC/FREE概述

3.1 MALLOC

  • malloc函数对应libc中的 _libc_malloc函数
  • _libc_malloc 仅是对 _ int_malloc 的封装,malloc的核心功能由 _int_malloc 实现
3.1.1 _LIBC_MALLOC
  1. 检查是否有内存分配函数的钩子函数(_malloc_hook)
    1. 如果有,则调用_malloc_hook指向的哈桑农户,并结束malloc
    2. 用于用户自定义的堆分配函数
  2. 寻找一个可供分配的arena
  3. 在指定的arena中申请对应的内存(_int_malloc)
  4. 如果分配失败,则尝试在其他的arena中分配
3.1.2 _INT_MALLO
  1. 将用户申请的内存大小转换为chunk大小
  2. 检查size的范围,先从bins中寻找是否有可用
    1. 如果符合fastbin大小,先在fastbin寻找
    2. 如果符合smallbin的大小,或者fastbin没有可用块,则在smallbin中寻找
    3. 如果都失败,调用malloc_consolidate函数,试图将fastbin的chunk合并,并将 合并后的chunk放入unsortedbin中(避免内存过于碎片化)
    4. 再将unsortedbin中的chunk依次取出判断,如果大小完全符合要求,则返回该 chunk;否则将chunk放入对应的bin(smallbin,largebin)
    5. 如果仍然失败,则从largebin中寻找最合适的块,必要时会切割chunk
  3. 到这里,说明bins中没有合适的chunk。此时将会从topchunk中切割

3.2 FREE

  • 和malloc函数类似,free函数对应libc中的 _libc_free函数
  • __libc_free 仅是对 _int_free 的封装, free 的核心功能由 _int_free 实现
3.2.1 __LIBC_FREE
  1. 检查是否有内存分配函数的钩子函数(__free_hook)
    1. 用于用户自定义的堆分配函数
  2. 判断当前chunk是否是mmap函数分配的,若是则调用munmap解除映射即
  3. 找到当前chunk所在的arena,并从该arena释放该chunk
3.2.2 _INT_FREE
  1. 对chunk进行简单检查
    1. 指针必须 2*SIZE_SZ 对齐(x64下即 0x10 对齐)
    2. chunk size必须大于 MINSIZE(x64下即 0x20)
    3. 检查其inuse标志
  2. 若chunk与topchunk相邻,则并入topchunk
  3. 检查chunk size的范围:
    1. 如果符合fastbin大小,则插入对应size的fastbin头部
    2. 如果不符合fastbin,就判断是否可以合并chunk——检查chunk物理地址相邻的前后chunk,若空闲则将它 们合并为一个大chunk。重复执行该步骤。
    3. 若发生了合并,且合并后chunk与topchunk相邻,也会并入topchunk,并结束。
    4. 将chunk放入对应的bin中(smallbin, largebin)

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

汇编语言基础知识 的相关文章

  • 软件测试|Python中如何提取列表中索引为奇数的元素

    简介 在Python中 我们经常需要从列表中提取特定位置的元素 如果我们想要提取列表中索引为奇数的元素 可以使用一些简单的方法来实现这一目标 本文将介绍如何在Python中提取列表中索引为奇数的元素 并提供示例代码来帮助大家更好地理解这个过
  • 什么是充放电振子理论?

    CHAT回复 充放电振子模型 Charging Reversal Oscillator Model 是一种解释ENSO现象的理论模型 这个模型把ENSO现象比喻成一个 热力学振荡系统 在这个模型中 ENSO现象由三个组成部分 充电 Char
  • 用CHAT分析高校体育智慧教学体系构建与探索研究现状

    CHAT回复 现阶段 高校体育智慧教学体系的构建与探索研究还处于初级阶段 但全球数字化转型大潮的推动下 一些较为前沿的研究和实践已经开始出现 1 教学平台的建设 很多高校已经开始尝试使用在线教育平台进行体育教学 把传统的面对面授课模式转变为
  • 软件测试|Python数据可视化神器——pyecharts教程(九)

    使用pyecharts绘制K线图进阶版 简介 K线图 Kandlestick Chart 又称蜡烛图 是一种用于可视化金融市场价格走势和交易数据的图表类型 它是股票 外汇 期货等金融市场中最常用的技术分析工具之一 可以提供关于价格变动 趋势
  • 基于java的学生成绩在线管理系统设计与实现

    基于java的学生成绩在线管理系统设计与实现 I 引言 A 研究背景和动机 基于Java的学生成绩在线管理系统设计与实现的研究背景和动机是设计一个可以方便管理学生成绩的系统 该系统可以方便地记录学生的成绩 并为老师和学生提供查询和统计功能
  • 【计算机毕业设计】白优校园社团网站的设计与实现

    近些年 随着中国经济发展 人民的生活质量逐渐提高 对网络的依赖性越来越高 通过网络处理的事务越来越多 随着白优校园社团网站的常态化 如果依然采用传统的管理方式 将会为工作人员带来庞大的工作量 这将是一个巨大考验 需要投入大量人力开展对社团
  • 华为OD机试 Java 【计算文件大小】

    题目 一个电脑文件夹系统 每个文件夹里都有一些文件和可能还有其他子文件夹 给定所有文件夹的大小和子文件夹列表 你的任务是找出某一个文件夹及其所有子文件夹里的文件总大小 输入格式 首行有两个数字 文件夹的总数M和你要查询的文件夹ID N 之后
  • 华为OD机试2024年最新题库(Java)

    我是一名软件开发培训机构老师 我的学生已经有上百人通过了华为OD机试 学生们每次考完试 会把题目拿出来一起交流分享 重要 2024年1月 5月 考的都是OD统一考试 C卷 题库已经整理好了 命中率95 以上 这个专栏使用 Java 解法 问
  • 一台java服务器可以跑多少个线程?

    一台java服务器可以跑多少个线程 一台java服务器能跑多少个线程 这个问题来自一次线上报警如下图 超过了我们的配置阈值 打出jstack文件 通过IBM Thread and Monitor Dump Analyzer for Java
  • Hutool改变我们的coding方式(二)

    Hutool改变我们的coding方式 Hutool 简介 Hutool如何改变我们的coding方式 文档 安装 Maven
  • 计算机Java项目|尤文图斯足球俱乐部网上商城系统

    作者简介 Java领域优质创作者 CSDN博客专家 CSDN内容合伙人 掘金特邀作者 阿里云博客专家 51CTO特邀作者 多年架构师设计经验 腾讯课堂常驻讲师 主要内容 Java项目 Python项目 前端项目 人工智能与大数据 简历模板
  • 最新整理Java面试八股文,大厂必备神器

    在看这篇文章之前 我想我们需要先搞明白八股文是什么 明清科举考试的一种文体 也称制义 制艺 时文 八比文 八股文章就四书五经取题 内容必须用古人的语气 绝对不允许自由发挥 而句子的长短 字的繁简 声调高低等也都要相对成文 字数也有限制 八股
  • Python 文件的复制重命名以及xlsx文件中表格分开保存

    1 需要的头文件 import shutil import os import openpyxl 2 复制文件以及重命名 直接使用shutil库复制 重命名 移动即可 函数封装示例 source path 为全局变量被复制文件路径 dest
  • 计算机Java项目|基于SSM的篮球系列网上商城设计与实现

    作者简介 Java领域优质创作者 CSDN博客专家 CSDN内容合伙人 掘金特邀作者 阿里云博客专家 51CTO特邀作者 多年架构师设计经验 腾讯课堂常驻讲师 主要内容 Java项目 Python项目 前端项目 人工智能与大数据 简历模板
  • 详解Java信号量-Semaphore

    第1章 引言 大家好 我是小黑 今天 咱们一起来深入探讨一下Semaphore 在Java中 正确地管理并发是一件既挑战又有趣的事情 当谈到并发控制 大家可能首先想到的是synchronized关键字或者是ReentrantLock 但其实
  • 【心电图基线估计和去噪方法的群稀疏正则化】带有群稀疏正则化的心电图基线估计和去噪(Matlab实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码及文章
  • 【心电图基线估计和去噪方法的群稀疏正则化】带有群稀疏正则化的心电图基线估计和去噪(Matlab实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码及文章
  • 基于节点电价的电网对电动汽车接纳能力评估模型研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码 数据
  • 【C#】基础巩固

    最近写代码的时候各种灵感勃发 有了灵感 就该实现了 可是 实现起来有些不流畅 总是有这样 那样的卡壳 总结下来发现了几个问题 1 C 基础内容不是特别牢靠 理解的不到位 导致自己想出来了一些内容 但是无法使用正确的C 代码实现 导致灵感无法
  • 软件测试/测试开发|给你剖析闭包与装饰器的魔力

    测试管理班是专门面向测试与质量管理人员的一门课程 通过提升从业人员的团队管理 项目管理 绩效管理 沟通管理等方面的能力 使测试管理人员可以更好的带领团队 项目以及公司获得更快的成长 提供 1v1 私教指导 BAT 级别的测试管理大咖量身打造

随机推荐

  • UML 类图

    1 概述 目录 1 概述 1 1 UML概念 1 2 类图的概念 2 类的表示方式 2 1 普通类 2 2 抽象类 2 3 接口 3 类与类关系的表示 3 1 关联关系 Association 3 1 1 单向关联 3 1 2 双向关联 3
  • 【小程序】如何实现从底部弹出对话框

    前面两篇两篇文章介绍了如何在小程序中实现上下滑动效果以及如何用 Canvas 绘制一张图片 这一篇作为前两篇的延续 介绍如何从底部弹出一个对话框 相比而言 底部弹出对话框的功能比较通用 因此非常适合定义成组件 component 先来看一下
  • 【学习记录贴】Vue+Element-UI富文本编辑框及插入图片

    本贴会涉及以下几个技术点 Vue Element UI实现富文本编辑框 以及文本编辑框中事件拦截 插入图片 Element UI限制上传图片后 隐藏上传按钮 官网上是没有这个方法的 可以通过上传到指定张数后隐藏上传按钮来实现 form表单验
  • MyBatis-Plus删除操作知识点总结

    系列文章目录 Mybatis Plus知识点 MyBatis MyBatis Plus的基础运用 心态还需努力呀的博客 CSDN博客 Mybatis Plus SpringBoot结合运用 心态还需努力呀的博客 CSDN博客MyBaits
  • VScode自由切换输出结果窗口,输出到“终端”和“调试控制台”

    Author xiaozhu sai 软件 Visual Studio Code 点击右边的齿轮按钮 打开launch json文件 注意 console 属性即可 具体见一下代码 使用 IntelliSense 了解相关属性 悬停以查看现
  • C++ sort函数自定义排序规则

    在使用vector容器时经常要进行排序 使用排序函数sort非常方便 但是之前都是简单调用sort v begin v end 没有自定义排序规则使用sort函数的额第三个参数 下面对sort总一个简单总结 头文件 include
  • 计算机网络第2章(物理层)

    B站视频 计算机网络微课堂 有字幕无背景音乐版 网址 https www bilibili com video BV1c4411d7jb p 61 目录 2 1 物理层的基本概念 2 2 物理层下面的传输媒体 导引型传输媒体 非导引型传输媒
  • Vue弹窗传值

    场景 点击新增后 需要将这个页面的分类Id传到弹窗页面 新增的时候绑定这个分类 步骤 1 列表页面中弹窗标签中绑定 classifyId this classify
  • 演唱会为什么总是抢不到票?用Python做一个自动抢票脚本!想看谁的就看谁的!

    大麦网 是中国综合类现场娱乐票务营销平台 业务覆盖演唱会 话剧 音乐剧 体育赛事等领域 但是因为票数有限 还有黄牛们不能丢了饭碗 所以导致了 很多人都抢不到票 那么 今天带大家用Python来制作一个自动抢票的脚本小程序 文章末尾看运行效果
  • Java 基于文本界面的《员工管理系统》

    一 代码实现 1 设计分析 该管理系统使用了5个包 Package 类似于文件夹 1 bean 包含员工类 Employee 2 main 主程序的入口 3 service 主要是 业务逻辑层 的功能实现 4 util 存放工具类 此处存放
  • 【springmvc系】利用RequestBodyAdviceAdapter做接口鉴权

    需求 有个简单的需求 对于第三方接口我们需要做个简单的鉴权机制 这边使用的是非对称性加密的机制 我们提供三方公钥 他们通过公钥对接口json报文使用加密后的报文请求 我们通过对接收过来的请求某一个加密报文字段来进行RSA解密校验 考虑到日后
  • hashmap原理_HashMap原理jdk7和jdk8的区别

    一 hashMap的jdk1 7和jdk1 8区别 1 实现方式 jdk7中使用数组 链表来实现 jdk8使用的数组 链表 红黑树 2 新节点插入到链表是的插入顺序不同 jdk7插入在头部 jdk8插入在尾部jdk7中 如何在头部插入 看a
  • [Hadoop3.3.1]:Unable to load native hadoop library for your platform

    需求 linux已经启动了hadoop集群 想要在windows中用java对文件进行下载操作 错误提示 找不到winutils exe hadoop dll没有设置原因 Hadoop访问windows本地文件系统 要求Windows上的本
  • SQL Server数据库进阶

    批处理 将多条SQL语句作为一个整体去编译 生成一个执行计划 然后执行 为了将一个脚本分为多个批处理 可使用GO语句 GO语句的特点 GO语句必须自成一行 只有注释可以在同一行上 它使得自脚本的开始部分或者最近一个GO语句以后的所有语句编译
  • elementUI中,实现一个单元格内显示两行数据,并用其中一个数据进行排序。

    最近在公司中 有这样一个需求 表格中 一个单元格里面显示两行数据 并且可以使用其中一行进行排序 其中数据的样式也要实时变动 类似于下图 这样的话 elementUI中自带的prop就不适合了 所以 需要展示两行数据的地方 我们就用插槽来解决
  • 重叠社区发现-UEOC算法(unfold and extract overlapping communities)学习笔记

    本文提出了一种基于马尔可夫动力学模型的发现节点共享社区的算法UEOC 在UEOC方法中 为了检测出所有的自然群落 将马尔可夫随机游动方法与一种新的约束策略相结合 该策略基于相应的退火网络 21 用于展开每个群落 然后 利用一个借助电导的截止
  • 【Python编程入门】环境搭建

    作为一门跨平台的高级编程语言 Python可以运行在几乎所有主流的操作系统中 这也意味着 只要我们在本机电脑安装配置完Python环境后 便可以轻松愉快的学习Python语言了 这是一门值得大部分人学习的计算机编程语言知识 关于Python
  • angular自定义form表单元素-checkList

    实际使用form的时候 最外层的form的某个表单元素可能是个组合的 这种情况如果是可多场景复用的 最好封装一个表单元素 本文以组合复选框为例来说明下自定义表单元素的过程 实现效果 展示效果 html
  • TeamViewer三种许可证的区别是什么?

    很多想要购买TeamViewer正版许可证的用户 不清楚这三种许可证的区别 所以今天小编就为大家介绍一下 这三种许可证到底有何区别以及购买那种最划算 首先为大家介绍一下TeamViewer Business商业版许可证 如下图所示 图1 B
  • 汇编语言基础知识

    文章目录 80386常用寄存器 一 常用寄存器 1 1 通用寄存器 1 2 段寄存器 1 3 程序状态与控制寄存器 二 常用基本指令 2 1 数据传送指令 2 2 算术运算指令 2 2 1 加法指令 2 2 2 减法指令 2 2 3 乘法指