最近在看c程序的编译出来的汇编文件,发现涉及到函数调用的地方,在返回时有的时候使用的leave,有的时候直接使用的是popl %ebp。
在AT&T汇编中,leave等效于以下汇编指令:
movl %ebp, %esp

popl %ebp

注意:此为32bits 操作系统,若为64bits 将使用rbp和rsp 寄存器!

为什么有的时候会使用leave,有的时候直接使用popl %ebp?这个问题一开始我也没搞懂,后来通过分析堆栈才有点清醒。
二者的差别就在于是否使用 movl %ebp, %esp。这句的作用是用来恢复堆栈的栈顶指针,是不是堆栈的栈顶指针没有变化的时候,
就可以不用恢复,直接使用popl指令了?这个疑惑经过验证被证实了。

main函数是一个最特殊的函数调用,就以它的调用过程为准。

[cpp] view plaincopy
  1. 原C代码如下:
  2. /*stack.c*/
  3. #include <stdio.h>
  4. int main()
  5. {
  6. return 0;
  7. }
[cpp] view plaincopy
  1. 通过gcc -S -o stack.s stack.c得到汇编代码
  2. .file   "stack.c"
  3. .text
  4. .globl  main
  5. .type   main, @function
  6. main:
  7. .LFB0:
  8. .cfi_startproc
  9. pushl   %ebp
  10. .cfi_def_cfa_offset 8
  11. .cfi_offset 5, -8
  12. movl    %esp, %ebp
  13. .cfi_def_cfa_register 5
  14. movl    $0, %eax    /*将返回值保存在eax中*/
  15. popl    %ebp        /*由于在该函数中,没有使用到栈,所以esp未变化,不需要恢复。*/
  16. .cfi_def_cfa 4, 4
  17. .cfi_restore 5
  18. ret
  19. .cfi_endproc
  20. .LFE0:
  21. .size   main, .-main
  22. .ident  "GCC: (GNU) 4.6.2 20111027 (Red Hat 4.6.2-1)"
  23. .section    .note.GNU-stack,"",@progbits
[cpp] view plaincopy
  1. 将c代码修改如下:
  2. #include <stdio.h>
  3. int main()
  4. {
  5. int c = 1;
  6. return 0;
  7. }
  8. 对应的汇编代码如下:
  9. .file   "stack.c"
  10. .text
  11. .globl  main
  12. .type   main, @function
  13. main:
  14. .LFB0:
  15. .cfi_startproc
  16. pushl   %ebp        /*原堆栈栈顶存放着原栈帧的ebp*/
  17. .cfi_def_cfa_offset 8
  18. .cfi_offset 5, -8
  19. movl    %esp, %ebp  /*将原堆栈地址放在ebp中,即新的栈帧的地址*/
  20. .cfi_def_cfa_register 5
  21. subl    $16, %esp   /*堆栈发生变化*/
  22. movl    $1, -4(%ebp)
  23. movl    $0, %eax
  24. leave           /*等效于 movl %ebp, esp; popl %ebp  首先需要恢复原栈顶指针,然后再根据栈顶指针恢复原栈帧的ebp*/
  25. .cfi_restore 5
  26. .cfi_def_cfa 4, 4
  27. ret
  28. .cfi_endproc
  29. .LFE0:
  30. .size   main, .-main
  31. .ident  "GCC: (GNU) 4.6.2 20111027 (Red Hat 4.6.2-1)"
  32. .section    .note.GNU-stack,"",@progbits

以上可以很清楚地看出leave的作用,和什么时候用leave,什么使用可以直接使用popl。

ATT汇编leave指令相关推荐

  1. ATT汇编——MOV指令

    AT&T汇编--MOV指令 MOV类指令 MOVZ类指令 MOVS类指令 MOV类指令 MOV类指令是最简单的数据传送指令,这类指令把数据从源位置复制到目的位置,不做任何变化. MOV类指令由 ...

  2. att格式汇编指令_关于ATT汇编

    ATT 汇编大体格式是: 指令 源操作数 目的操作数 ,比如将 10 移动到 eax 寄存器的写法: movl $10, %eax . 1.ATT 汇编的源操作数和目的操作数和 Intel 正好相反, ...

  3. ATT汇编指令 AT&T汇编伪指令

    最近一直在看OS方面的东西,其中要用到许多AT&T汇编,下面是在网上打到的关于它的伪指令方面的中英文对照版本.英文版本也可以输入如下命令来查看:     info as        read ...

  4. C指针原理(21)-C指针基础-ATT汇编

    helloworld-高级版 .section .data#初始化的变量 output:.ascii "hello,world\n"#要打印的字符串,.data为初始化值的变量.o ...

  5. 80×86汇编常用指令

    80×86汇编常用指令 一.数据传送指令 1. 通用数据传送指令 简写 英文全称 执行操作 MOV move 传送 MOVSX move with sign-extend 带符号扩展传送 MOVZX ...

  6. 微机原理8086汇编语言上机——Masm环境搭建与常用汇编调试指令

    学校的微机原理与接口技术课,最近开始 考古 上机实验了. 1.弯路 为什么不用宇宙最强大的IDEL--Visual Studio呢? 在我的Visual Studio专栏中有一篇文章介绍Visual ...

  7. 汇编语言基础--汇编操作指令概述

    本文是接续"汇编语言基础--机器级数据存储",主要介绍汇编指令的构造.寻址和指令主要分类. 操作指令 指令的基本要素:       在"计算机处理器(CPU)基础&quo ...

  8. [逆向]汇编JCC指令举例

    一前言 今天文章的主要内容是逆向基础汇编JCC指令举例,JCC指令就是满足条件跳转指令,上一篇文章已经给大家介绍了基本用法,如有不明白的可以先看看我的上一篇文章,今天主要为大家举例加强巩固. 二JCC ...

  9. 木马免杀之汇编花指令技巧

    木马免杀之汇编花指令技巧 作者: 逆流风(发表于<黑客X档案>07.07,转载注明出处)        相信很多朋友都做过木马免杀,早期的免杀都是加壳和改特征码,现在免杀技术已经发展到花指 ...

最新文章

  1. 关于虚拟机的三种网络接口模式(以VXBOX虚拟机为例)
  2. UVALive 7040 Color
  3. zigbee绑定 使用_遇见-果加智能锁F2——使用体验
  4. selenium自动化测试、Python单元测试unittest框架以及测试报告和日志输出
  5. TCP/IP详解学习笔记(2)-数据链路层
  6. java拦截器_Java工程师年底跳槽高潮即将到来,斩获满意offer的必备技巧(二)
  7. SAP Spartacus使用cxComponentWrapper测试MiniCart
  8. Arm-Linux 编译Asterisk
  9. 【渝粤教育】电大中专消费者行为学 (2)作业 题库
  10. 施乐s2110进入维修模式_施乐进入维修模式步骤
  11. native2ascii编码转换
  12. linux显卡驱动编译安装,联想Y470下CentOS 6.4 AMD显卡驱动编译安装与配置
  13. 如何维持手机电池寿命_教你一招,可以让你的手机电池容量长期维持在峰值,延长电池寿命...
  14. 计算机音乐专业考研,武汉音乐学院2021年硕士研究生招生考试《计算机音乐作曲》考试大纲...
  15. CF卡插到时显示函数不正确请问咋才能修复?
  16. MOOS-ivp app发布车辆位置及控制车辆运动
  17. 同一个类中不同方法之间的互相调用
  18. 计算机表格怎么加减乘除,在EX表格里怎么进行加减乘除法的计算
  19. 7-6 jmu-Java-01入门-开根号
  20. java怎么无参构造方法_Java中如何在无参构造方法中调用有参构造?

热门文章

  1. LeetCode 53. 最大子序和(Maximum Subarray)
  2. NYOJ 330 一个简单的数学题
  3. STL之set集合容器
  4. 锁定文件失败 打不开磁盘“D:\vms\S1\CentOS 64 位.vmdk”或它所依赖的某个快照磁盘(强制关机后引起的问题)...
  5. npm和node.js升级
  6. Docker 配置固定IP及桥接的实现方法(转载)
  7. Deepin系统更新apt-get源
  8. AndroidStudio-引用jar包及so文件
  9. shell脚本中的括号和实例
  10. 实验一 OpenGL初识