博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
一个简单程序的汇编执行过程分析
阅读量:5461 次
发布时间:2019-06-15

本文共 2718 字,大约阅读时间需要 9 分钟。

  • 题目自拟,内容围绕计算机是如何工作的进行;
  • 博客中需要使用实验截图
  • 博客内容中需要仔细分析汇编代码的工作过程中堆栈的变化
  • 总结部分需要阐明自己对“计算机是如何工作的”理解。

实验环境:ubuntu64位

源代码:

int g(int x){    return x + 4;}int f(int x){    return g(x);}int main(){    return f(10) + 5;}

 

编译命令:

gcc -S -o anlysis_assemble.s anlysis_assemble.c -m32 //

生成的汇编代码为:

.file    "anlysis_assemble.c"    .text    .globl    g    .type    g, @functiong:.LFB0:    .cfi_startproc    pushl    %ebp    .cfi_def_cfa_offset 8    .cfi_offset 5, -8    movl    %esp, %ebp    .cfi_def_cfa_register 5    movl    8(%ebp), %eax    addl    $4, %eax    popl    %ebp    .cfi_restore 5    .cfi_def_cfa 4, 4    ret    .cfi_endproc.LFE0:    .size    g, .-g    .globl    f    .type    f, @functionf:.LFB1:    .cfi_startproc    pushl    %ebp    .cfi_def_cfa_offset 8    .cfi_offset 5, -8    movl    %esp, %ebp    .cfi_def_cfa_register 5    subl    $4, %esp    movl    8(%ebp), %eax    movl    %eax, (%esp)    call    g    leave    .cfi_restore 5    .cfi_def_cfa 4, 4    ret    .cfi_endproc.LFE1:    .size    f, .-f    .globl    main    .type    main, @functionmain:.LFB2:    .cfi_startproc    pushl    %ebp    .cfi_def_cfa_offset 8    .cfi_offset 5, -8    movl    %esp, %ebp    .cfi_def_cfa_register 5    subl    $4, %esp    movl    $10, (%esp)    call    f    addl    $5, %eax    leave    .cfi_restore 5    .cfi_def_cfa 4, 4    ret    .cfi_endproc.LFE2:    .size    main, .-main    .ident    "GCC: (Ubuntu 4.8.2-19ubuntu1) 4.8.2"    .section    .note.GNU-stack,"",@progbits

删除伪代码,最简化后的代码为:

g:    pushl   %ebp    movl    %esp, %ebp    movl    8(%ebp), %eax    addl    $4, %eax    popl    %ebp    retf:    pushl    %ebp        movl    %esp, %ebp    subl    $4, %esp    movl    8(%ebp), %eax    movl    %eax, (%esp)    call    g    leave    retmain:    pushl   %ebp    movl    %esp, %ebp    subl    $4, %esp    movl    $10, (%esp)    call    f    addl    $5, %eax    leave    ret

 首先对push指令进行分析:

pushl %eax 等价于以下两句:

subl $4, %esp            # esp = esp - 4, 栈向下增长, 栈顶指针向下增长

movl %eax, (%esp) # 将寄存器eax内容取出到esp指向的地址的内存,即栈顶位置

分析pop指令:

popl %eax 等价于以下两句:

movl (%esp), %eax  # 将esp指向的栈顶处内存值赋值给eax 

addl $4, %esp          # esp栈顶向上缩小

可以用这两个指令替代push 或 pop

分析call指令

call 0x12345 等价与以下两句:

pushl %eip

movl $0x12345, %eip

分析 ret 指令

ret 等价与 popl %eip

这里注意的是eip不能在写汇编代码时直接修改,只能间接修改

分析几段汇编指令片段

例子一

pushl $8  # 假设当前栈为空,栈顶和栈底都指向相同地址,esp = esp - 4, %esp = 8

movl %esp, %ebp #则ebp也指向esp的位置

subl $4,%esp #esp向下移动一个位置

movl $8, (%esp) # 将8赋值到栈顶位置

例子二

pushl $8

movl %esp, $ebp

pushl %esp  # 将当前位置放到栈中

pushl $8

addl $4, %esp

popl %esp

分析leave和enter指令,它们分别由两条指令组成

enter: #进入函数调用堆栈

  pushl %ebp

  movl %esp, %ebp

leave: #撤销函数调用堆栈

  movl %ebp, %esp

  popl %ebp

 

函数调用堆栈是由逻辑上多个堆栈叠加起来的。

ebp , esp是相对的栈底和栈顶,每个函数都有自己的栈顶和栈底

函数的返回值默认使用eax寄存器返回给上一级函数

 

转载于:https://www.cnblogs.com/jinee/p/4536945.html

你可能感兴趣的文章
vs code 快捷键大全
查看>>
mysql注意:
查看>>
[1,2,3,4,5,6,7,8] 转换成 [(1,2),(2,3),(3,4),(4,5),(5,6),(6,7),(7,8)] ...
查看>>
彻底删除mysql 分类: database 201...
查看>>
ARM指令集中立即数寻址的范围
查看>>
学习:关于oracle序列(sequence)组成的主键和唯一的字符串组成的主键在性能上如何?...
查看>>
用一道面试题考察对闭包的理解
查看>>
android中判断某个应用是否存在
查看>>
How to change SAPABAP1 schema password In HANA
查看>>
mimics教程中文版——第二章
查看>>
Go并发编程实践
查看>>
CSS margin详解
查看>>
cesium编程入门(三)开始使用cesium开发
查看>>
4.18n阶勒让德多项式求解
查看>>
RTMP协议分析及推流过程
查看>>
PAT天梯赛L1-054 福到了
查看>>
Pains and Sickness 学习笔记
查看>>
PHP变量测试函数
查看>>
第六天 基本文件管理与XFS文件系统备份恢复
查看>>
win10中强制vs2015使用管理员启动
查看>>