• 编译原理—x86汇编指令


    eax, ebx, ecx, edx, esi, edi, ebp, esp寄存器
    eax, ebx, ecx, edx, esi, edi, ebp, esp等都是X86 汇编语言中CPU上的通用寄存器的名称,是32位的寄存器。如果用C语言来解释,可以把这些寄存器当作变量看待。

    比方说:add eax,-2 ; //可以认为是给变量eax加上-2这样的一个值。

    这些32位寄存器有多种用途,但每一个都有“专长”,有各自的特别之处。

    eax 是"累加器"(accumulator), 它是很多加法乘法指令的缺省寄存器。

    ebx 是"基地址"(base)寄存器, 在内存寻址时存放基地址。

    ecx 是计数器(counter), 是重复(REP)前缀指令和LOOP指令的内定计数器。

    edx 则总是被用来放整数除法产生的余数。

    esi, edi,分别叫做"源/目标索引寄存器"(source/destination index),因为在很多字符串操作指令中, DS:ESI指向源串,而ES:EDI指向目标串.

    ebp是"基址指针"(BASE POINTER), 它最经常被用作高级语言函数调用的"框架指针"(frame pointer). 在破解的时候,经常可以看见一个标准的函数起始代码:

    push ebp ;保存当前ebp
    mov ebp,esp ;EBP设为当前堆栈指针
    sub esp, xxx ;预留xxx字节给函数临时变量.
    
    • 1
    • 2
    • 3

    这样一来,ebp 构成了该函数的一个框架, 在ebp 上方分别是原来的ebp , 返回地址和参数. ebp 下方则是临时变量. 函数返回时作 mov esp,ebp/pop ebp/ret 即可.

    esp 专门用作堆栈指针,被形象地称为栈顶指针,堆栈的顶部是地址小的区域,压入堆栈的数据越多,esp 也就越来越小。在32位平台上,esp 每次减少4字节。

    mov指令\add sub指令

    push ebp ;保存当前ebp
    mov ebp,esp ;EBP设为当前堆栈指针
    sub esp, xxx ;预留xxx字节给函数临时变量.

    mov ax,18 将 1 8送入寄存器AX AX=18
    mov ah,78 将 7 8送入寄存器AH AH=78
    add ax,8 将寄存器A X 中的数值加上8 AX=AX+8
    mov ax,bx 将寄存器B X 中的数据送入寄存器AX AX=BX
    add ax,bx 将 A X B X 中的数值相加,结果存在A X AX=AX+BX

    mov指令可以有以下几种形式。
    mov 寄存器,数 比如: mov ax,8
    mov 寄存器,寄存器 比如: mov ax,bx
    mov 寄存器,内 单 比如: mov ax,[0]
    mov 内 单 ,寄存器 比如: mov [0],ax
    mov 段寄存器,寄存器 比女口 :mov ds,ax
    那么ESP和EBP指的分别是什么呢?

    add sub指令同mov— ,都有两个操作对象。它们也可以有以下几种形式。
    add 寄存器,数 比如:add ax,8
    add 寄存器,寄存器 比如:add ax,bx
    add 寄存器,内 单 比如:add ax,[0]
    add 内 单 ,寄存器 比如:add [0],ax
    sub 寄存器,数 比如:sub ax,9
    sub 寄存器,寄存器 比如:sub ax,bx
    sub 寄存器,内 单 比如:sub ax,[0]
    sub 内 单 ,寄存器 比如:sub [0],ax

    (1)ESP:栈指针寄存器(extended stack pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶。
    (2)EBP:基址指针寄存器(extended base pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的底部。

    JGE JLE JNE JL JG JE指令\INC DEC指令

    INC 自增1 increase
    DEC 自减1 decrease
    JGE 前>=后 Jump if greater or equal
    JG 前>后 Jump if greater
    JLE 前<=后 Jump if less or equal
    JL 前<后 Jump if less
    JNE 前不等于后 Jump if not equal
    JE 前等于后 Jump if equal

    (a)简要注释每条汇编代码;
    .file "foo.c" //表示汇编来源的原始文件名 
    .text //代码开始 
    .globl fact //定义一个全局符号,fact 作为函数名
    .type fact,@function //定义符号 fact 的类型为一个 function 
    fact: //局部函数 fact 开始
    pushl %ebp //将 ebp 寄存器中长字类型的内容压入栈中 
    movl %esp, %ebp //将 esp 中的内容传送到 ebp 中 
    subl$4, %esp //esp 指针向下移动 4 个字节,给局部变量留出空间
    cmpl $0, 8(%ebp) //将 ebp+8 所对应地址中的数与 0 作比较 
    jg .L2 //若比较结果大于 0 则跳转至 L2 
    movl $1, -4(%ebp) //将立即数 1 存入 ebp-4 所对应的地址 
    jmp .L1 //跳转至 L1 
    .L2:
    subl$12, %esp //esp 指针向下移动 12 个字节 
    movl 8(%ebp), %eax //将 ebp+8 对应地址的内容送入 eax 中 
    decl%eax //执行减一指令,eax 中存的数值减一
    pushl %eax //将 eax 中的内容入栈 
    call fact //调用 fact 函数 
    addl$16, %esp //让 esp 指向 esp+16 所对应的地址单元 
    imull 8(%ebp), %eax //将 ebp+8 对应地址的内容与 eax 中内容相乘并
    存入 eax 
    movl %eax, -4(%ebp) //将 eax 中的内容送入 ebp-4 对应的地址中
    .L1:
    movl -4(%ebp), %eax //将 ebp-4 对应地址中的内容送入 eax 中 
    leave //关闭栈帧 
    ret //恢复断点,返回主程序 
    .Lfe1:
    .size fact,.Lfe1-fact //fact 函数大小
    .ident "GCC: (GNU) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)"//编译器标识
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
  • 相关阅读:
    卷绕工艺与叠片工艺的对比
    分类预测 | Matlab实现PSO-BiLSTM粒子群算法优化双向长短期记忆神经网络的数据多输入分类预测
    k8s驱逐篇(4)-kube-scheduler抢占调度驱逐
    【CEOI2022】Drawing(全局平衡二叉树,构造,分治)
    测开 - 测试管理工具禅道篇 - 细节狂魔
    图像处理:单通道转为3通道
    lement-ui 加载本地图片
    [设计模式Java实现附plantuml源码~行为型]定义算法的框架——模板方法模式
    python实现AES加密解密
    128. SAP UI5 智能控件 Smart Controls 的初步认识
  • 原文地址:https://blog.csdn.net/weixin_56462041/article/details/128069491