反汇编一个简单的C程序

1、实验要求

使用:

gcc –S –o test.s test.c -m32

命令编译成汇编代码,对汇编代码进行分析总结。其中test.c的具体内容如下:

int g(int x)
{
return x + 3;
} int f(int x)
{
return g(x);
} int main(void)
{
return f(8) + 1;
}

2、实验过程

  • 使用vim对test.c进行编辑,将上述代码键入
  • 使用gcc对test.c编译,产生test.s文件
gcc -S -o test.s test.c -m32

如下图所示:

  • 使用vim查看test.s文件

    查看test.s文件,如下图所示:



    “.”开通的所有代码为链接时候的辅助信息,不会被实际执行,我们可以把这些代码删除,删除后的代码即为纯净的汇编代码,如下图所示:

3、实验分析

  • 寄存器&寻址方式

    • 通用寄存器:

      • AX:累加器
      • BX:基地址寄存器
      • CX:计数寄存器
      • DX:数据寄存器
      • BP:堆栈基址针
      • SI、DI:变址寄存器
      • SP:堆栈顶指针
    • 段寄存器
      • CS:代码段寄存器,指向包含程序指令的段。
      • SS:栈段寄存器,指向包含当前程序栈的段。
      • DS:数据段寄存器,指向包含静态数据或者全局数据段。
      • ES:附加寄存器,指向附加数据段。
    • 寻址方式
      • movl %eax,%edx <-> edx=eax 寄存器寻址
      • movl $0x123,%edx <-> edx=0x123 立即寻址
      • movl 0x123,%edx <-> edx=*(int32_t*)0x123 直接寻址
      • movl (%ebx),%edx <-> edx=*(int32_t*)ebx 间接寻址
      • movl 4(%ebx),%edx <-> edx=*(int32_t*)(ebx+4) 变址寻址
  • 汇编代码流程分析

    • 汇编代码依然从main函数读起

      • eip寄存器从main函数起自+1,指向当前执行的指令语句(未遇到特殊指令时)
      • ebp寄存器始终指向栈底,esp寄存器始终指向栈顶,eax寄存器用来暂存一些数值(如函数的返回值)
      • ebp入栈
      • 把ebp值赋予给esp
      • 将esp值减4,指向下一栈存储空间
      • 将数值2018存在esp所指的存储空间中
    • 调用f函数

      • ebp入栈
      • 把ebp值赋予给esp
      • 将esp减4,指向下一栈地址空间
      • 将ebp变址寻址8,即向上退两个栈空间,并将此空间值赋给eax
      • 将eax的内容赋予给esp
    • 调用g函数

      • 对ebp进行压栈
      • 把ebp值赋予给esp
      • 将ebp变址寻址8,即向上退两个栈空间,并将此空间值赋给eax
      • 将eax储存的数值加9228
      • 出栈
      • 返回f函数call语句的下一句(leave)
    • 返回main函数

      • 返回main的call指令下一句(addl)
      • 将eax储存的数加9228
      • esp指向ebp位置,ebp指向栈中指向的位置(leave作用)
      • 返回
  • 堆栈变化分析

    初始化状态esp和ebp都在栈底:



    后指令代码从main函数顺序执行:







    执行到call f指令,eip记录call指令的下一条语句位置,此时代码跳转至f函数执行:













    执行到call g指令,eip记录call指令下一条语句位置,此时代码跳转至g函数执行:









    此时,g函数执行到ret,返回f函数call的下一条语句leave:











    至此,整个指令运行完成,堆栈为空。

4、实验总结

汇编语言是计算机的低级语言,真正的深入了解汇编语言对于我们深入理解计算机系统有着极大的帮助,更是为我们未来linux内核分析的深入学习打下坚实基础。本次使用C语言反编译成汇编语言,利用我们熟悉的C语言代码来对照理解汇编指令代码、分析堆栈的变化让我们更好的理解计算机在执行程序的时候是如何工作的。具体来说:

  • 加深了esp、ebp、eip以及eax各自作用的印象
  • 更好的理解了变址寻址的具体过程
  • 更加熟悉了常用的汇编指令
  • 了解了计算机在执行程序时是如何工作的

其他问题

在进行makefile的测试时,在vim中写好了Makefile,在进行make时,shell提示没有找到make指令,我意识到应该是没有内置此指令,便使用sudo apt-get install make获取make指令,但shell提示:

sudo: /usr/bin/sudo must be owned by uid 0 and have the setuid bit set

应该是账户的权限不够,但我想要切换到系统内置的root账户,要求我输入密码,但我好像并不知道root的密码……

经过一系列的资料查询,参考了此篇博文的方法,进入recovery模式更改root账户密码。重启后,使用root账户,sudo apt-get install make执行成功,make命令成功安装。

出现这样的小插曲,也算是在本次作业之外的一个小收获。

《Linux内核原理与分析》第二周作业的更多相关文章

  1. 2019-2020-1 20199303<Linux内核原理与分析>第二周作业

    2019-2020-1 20199303第二周作业 1.汇编与寄存器的学习 寄存器是中央处理器内的组成部份.寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令.数据和位址.在中央处理器的控制部件中 ...

  2. 20169219 linux内核原理与分析第二周作业

    "linux内核分析"的第一讲主要讲了计算机的体系结构,和各寄存器之间对数据的处理过程. 通用寄存器 AX:累加器 BX:基地址寄存器 CX:计数寄存器 DX:数据寄存器 BP:堆 ...

  3. 2019-2020-1 20199314 <Linux内核原理与分析>第二周作业

    1.基础学习内容 1.1 冯诺依曼体系结构 计算机由控制器.运算器.存储器.输入设备.输出设备五部分组成. 1.1.1 冯诺依曼计算机特点 (1)采用存储程序方式,指令和数据不加区别混合存储在同一个存 ...

  4. Linux内核原理与分析-第二周作业

    写之前回看了一遍秒速五厘米:如果

  5. Linux内核原理与分析-第一周作业

    本科期间,学校开设过linux相关的课程,当时的学习方式主要以课堂听授为主.虽然老师也提供了相关的学习教材跟参考材料,但是整体学下来感觉收获并不是太大,现在回想起来,主要还是由于自己课下没有及时动手实 ...

  6. 2019-2020-1 20199314 <Linux内核原理与分析>第一周作业

    前言 本周对实验楼的Linux基础入门进行了学习,目前学习到实验九完成到挑战二. 学习和实验内容 快速学习了Linux系统的发展历程及其简介,学习了下的变量.用户权限管理.文件打包及压缩.常用命令的和 ...

  7. 2018-2019-1 20189221《Linux内核原理与分析》第一周作业

    Linux内核原理与分析 - 第一周作业 实验1 Linux系统简介 Linux历史 1991 年 10 月,Linus Torvalds想在自己的电脑上运行UNIX,可是 UNIX 的商业版本非常昂 ...

  8. 2020-2021-1 20209307 《Linux内核原理与分析》第九周作业

    这个作业属于哪个课程 <2020-2021-1Linux内核原理与分析)> 这个作业要求在哪里 <2020-2021-1Linux内核原理与分析第九周作业> 这个作业的目标 & ...

  9. 20169212《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 这一周学习了MOOCLinux内核分析的第一讲,计算机是如何工作的?由于本科对相关知识的不熟悉,所以感觉有的知识理解起来了有一定的难度,不过多查查资 ...

  10. 20169210《Linux内核原理与分析》第二周作业

    <Linux内核原理与分析>第二周作业 本周作业分为两部分:第一部分为观看学习视频并完成实验楼实验一:第二部分为看<Linux内核设计与实现>1.2.18章并安装配置内核. 第 ...

随机推荐

  1. 7.26-Codeforces Round #372 (Div. 2)

    C. Plus and Square Root 链接:codeforces.com/group/1EzrFFyOc0/contest/716/problem/C 题型:构造 题意:起始数 x 为 2, ...

  2. Learning-MySQL【1】:数据库初识及 MySQL 的安装

    一.什么是数据 数据(Data):描述事务的符号记录,描述事物的符号既可以是数字,也可以是文字.图片,图像.声音.语言等,数据由多种表现形式,它们都可以经过数字化后存入计算机 在计算机中描述一个事物, ...

  3. webpack4入门

    前提 已安装node(版本号>4.0,已自带NPM) mac机器 有一个空目录 无webpack.config.js配置打包 快速构建package.json文件. npm init -y 安装 ...

  4. Pandas 基础(6) - 用 replace() 函数处理不合理数据

    首先, 还是新建一个 jupyter notebook, 然后引入 csv 文件(此文件我已上传到博客园): import pandas as pd import numpy as np df = p ...

  5. fastjson将json字符串转化成map的五种方法

    package com.zkn.newlearn.json; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObj ...

  6. 菜鸟脱壳之脱壳的基础知识(二) ——DUMP的原理

    菜鸟脱壳之脱壳的基础知识(二)——DUMP的原理当外壳的执行完毕后,会跳到原来的程序的入口点,即Entry Point,也可以称作OEP!当一般加密强度不是很大的壳,会在壳的末尾有一个大的跨段,跳向O ...

  7. Vue入门笔记(一)--基础部分

    github地址:https://github.com/iTao9354/basicVue(demo01-28) 一.初识Vue 使用双大括号{{message}}将数据渲染进DOM中.      可 ...

  8. 【协议逆向工程】Part 1 概述

    1 协议逆向工程概述 1.1 协议 协议是计算机网络与分布式系统中各种通信实体键相互交互信息时必须遵守的一组规则和约定,这些规则明确规定了所交换的数据格式以及有段的同步问题,从而保证了双方通信有条不紊 ...

  9. react 表单获取多个input

    react  表单this.handleChange(key,e){ [key]:e.target.value} submit=()=>{ const {userName,age,status} ...

  10. webassembly

    为什么需要 WebAssembly 自从 JavaScript 诞生起到现在已经变成最流行的编程语言,这背后正是 Web 的发展所推动的.Web 应用变得更多更复杂,但这也渐渐暴露出了 JavaScr ...