Linux下程序的机器级表示学习心得
Linux下程序的机器级表示学习心得
上周学习完Linux程序的机器级表示后,对于其中有些还是掌握的不太透彻。对于老师提出的关于本章一些细节的问题还是有不会,所以又重新温习了一下上周的学习内容,以下为学习心得。
分析反汇编
操作过程
分析反汇编采用了书上的一个简单案例。C语言代码如下。
int a(int x)
{
returnx+1;
} int b(int x)
{
return a(x);
} int main (void)
{
return b(8)+14;
}
使用
vim
编辑器编译代码main.c
。
使用命令
gcc -S main.c -o main.s
得到汇编代码。(此时的汇编代码有以.开头的代码,删除它们之后就是正常书中给出的汇编代码。得到的汇编代码
使用
gdb
的bt/frame/up/down
指令动态查看调用线帧的情况。
分析
从
main
:开始执行,保存帧指针%ebp
,并设置新的帧指针pushl $8
分配4字节的栈空间,并且设置arg1=8
调用b:
call b
b同样初始化帧指针,分配栈空间,和之前的main函数相同
pushl 8(%ebp)
将%esp
中的立即数8存入栈中调用a:
call a
a被调用,初始化栈指针,分配栈空间
将
%eax
与立即数 1 相加在a结束前弹栈
ret
返回b中call
的调用位置b也结束,
return返
回main
中call
调用的位置main
继续%eax
加14的操作leave
为返回准备栈,相当于%ebp
出栈,最后ret
结束
即:调用者P和被调用者Q,则Q的参数放在P的栈帧中,当P调用Q的时候,P中的返回地址被压入栈中,形成P的栈帧末尾。返回地址就是当程序从Q返回时应继续执行的地方,Q栈帧从保存的帧指针的值开始后是保存其他寄存器的值。
结合backtrace命令分析栈帧
首先
backtrace/bt
用来打印栈帧指针,也可以在该命令后加上要打印的栈帧的个数,查看程序执行到此时,是经过哪些函数呼叫的程序,程序“调用堆栈”是当前函数之前的所有已调用函数的列表(包括当前函数)。每个函数及其变量都分配了一个“帧”,最近调用的函数在0号帧中(“底部”帧)命令有
- `fame farme1 `用于打印指定栈帧
- ` info reg `查看寄存器使用情况
- ` info stack` 产看堆栈使用情况
- `up/down` 跳到上一层/下一层函数
综述:
- 先将调用者(A)的堆栈的基址(`%ebp`)入栈,以保存之前任务的信息。 - 然后将调用者(A)的栈顶指针(`%esp`)的值赋给`%ebp`,作为新的基址(即被调用者B的栈底)。 - 然后在这个基址(被调用者B的栈底)上开辟(一般用sub指令)相应的空间用作被调用者B的栈空间。 - 函数B返回后,从当前栈帧的%ebp即恢复为调用者A的栈顶(`%esp)`,使栈顶恢复函数B被调用前的位置;然后调用者A再从恢复后的栈顶可弹出之前的%ebp值(可以这么做是因为这个值在函数调用前一步被压入堆栈)。这样,`%ebp`和`%esp`就都恢复了调用函数B前的位置,也就是栈恢复函数B调用前的状态。这样就解释了栈帧的出现和消失
这个过程在AT&T汇编中通过两条指令完成,即:
leave
、ret
。这两条指令更直白点就相当于:mov %ebp , %esp
、pop %ebp
- 下面我们使用GDB调试
main.c
的代码,使用刚才编译好的main镜像。
-gdb start
(启动gdb)
-(gdb) file main
(加载镜像文件)
-(gdb) break main
(把main()
设置为断点,注意gdb并没有把断点设置在main的第一条指令,而是设置在了调整栈指针为局部变量保留空间之后)
-(gdb) run
(运行程序)
-(gdb) stepi
(单步执行,stepi
命令执行之后显示出来的源代码行或者指令地址,注意:都是即将执行的指令,而不是刚刚执行完的指令!对于更复杂的例子会有明显的变化)
利用gdb对寄存器进行分析
通过gdb调试可执行文件查看
%eip
,%ebp
,%esp
等寄存器内容如何变化。
在linux中gdb调试汇编文件需要先用
gcc -g3 -o * *.c
的命令来将c语言文件编译成可调试汇编的可执行文件。通过调试过程中的
stepi
和print /x $***
可以查询到相应寄存器的内容:根据之前的main函数逐步使用上面的代码,可以获得不同寄存器的变化。
| number | %eax寄存器变化| %esp寄存器变化|%ebp寄存器变化时间|
| -----------| :-----------:|:------------:|:---------------:|
| 1 | Ox4004fc | Oxffffde18 | Oxffffde20
| 2 | Ox4004fc | Oxffffde18 | Oxffffde20
| 3 | Ox8 | Oxffffde18 | Oxffffde20
| 4 | Ox8 | Oxffffde18 | Oxffffde20
| 5 | Ox8 | Oxffffde10 | Oxffffde20
| 6 | Ox8 | Oxffffde08 | Oxffffde20
| 7 | Ox8 | Oxffffde08 | Oxffffde08
| 8 | Ox8 | Oxffffde08 | Oxffffde08
| 9 | Ox8 | Oxffffde08 | Oxffffde08
| 10 | Ox9 | Oxffffde08 | Oxffffde08
| 11 | Ox9 | Oxffffde10 | Oxffffde20
| 12 | Ox9 | Oxffffde18 | Oxffffde20
| 13 | Ox9 | Oxffffde28 | Oxffffde30
| 14 | Ox9 | Oxffffde30 | Oxffffde30
| ... | ... | ... | ...
如果想观察三个寄存器的每一步的变化配合
gdb stepi
可以重复上述步骤。部分过程截图。
由上图可以看到三个寄存器的初始值
由上图可以看到三个寄存器在执行完第一条指令之后的内容的变换
注意:在64位中
rip
就是eip
,rbp
就是ebp
,rsp
就是。
Linux下程序的机器级表示学习心得的更多相关文章
- CSAPP:第三章程序的机器级表示3
程序的机器级表示3 关键点:过程.调试.指针 过程1.运行时栈2.转移控制3.数据传递4.栈上的局部存储5.寄存器中的局部存储空间理解指针使用GDB调试器 过程 1.运行时栈 x86-64的栈向低 ...
- CSAPP:第三章程序的机器级表示2
CSAPP:程序的机器级表示2 关键点:算术.逻辑操作 算术逻辑操作1.加载有效地址2.一元二元操作3.移位操作 算术逻辑操作 如图列出了x86-64的一些整数和逻辑操作,大多数操作分成了指令类( ...
- CS:APP Chapter 3 程序的机器级表示-读书笔记
3.1 程序的机器级表示 发展历史 Intel,AMD,ARM 等企业各有又是,CPU 从 8 位发展到 16 位,再到 32 位,近几年发展到 64 位,当下的 CPU 体系被称为 x86-64 体 ...
- Windows 7 下如何设置机器级别的DCOM权限
Windows 7 下如何设置机器级别的DCOM权限 To grant Remote Activation permissions to the SMS Admins group From the S ...
- Linux下 两台机器文件/文件夹 相互拷贝
Linux下 两台机器文件/文件夹 相互拷贝 设有两台机器 :A:*.101及 B:*.102. 把A下的.temp/var/a.txt拷贝到B机器的/text/目录下: 进入B机器:scp root ...
- CSAPP:第三章程序的机器级表示1
CSAPP:程序的机器级表示1 关键点:数据格式.操作数指示符. 数据格式访问信息操作数指示符举例说明 数据格式 术语字(word)表示16位数据类型,32位数为双字(double words), ...
- 六星经典CSAPP-笔记(3)程序的机器级表示
1.前言 IA32机器码以及汇编代码都与原始的C代码有很大不同,因为一些状态对于C程序员来说是隐藏的.例如包含下一条要执行代码的内存位置的程序指针(program counter or PC)以及8个 ...
- CSAPP 3 程序的机器级表示
1 本章总述 1) 通过让编译器产生机器级程序的汇编表示, 学习了编译器及其优化能力, 以及机器.数据类型和指令集; 2) 学习了程序如何将数据存储在不同的内存区域中 -- 程序开发人员需要知道一个变 ...
- 深入理解计算机系统 第三章 程序的机器级表示 Part2 第二遍
第一遍对应笔记链接 https://www.cnblogs.com/stone94/p/9943779.html 本章汇编代码中常出现的几个指令及其含义 1.push 操作数的个数:1 将操作数(一般 ...
随机推荐
- node.js创建server服务---sublime 的node及typescript环境配置
一.初始环境搭建 mkdir server //创建server文件夹 cd server //进入到创建的文件夹目录下 npm init -y //生成含有默认配置的package.json文件 n ...
- js 高程 函数节流 throttle() 分析与优化
在 js 高程 22.3.3章节 里看到了 函数节流 的概念,觉得给出的代码可以优化,并且概念理解可以清晰些,所以总结如下: 先看 函数节流 的定义,书上原话(斜体表示): 产生原因/适用场景: 浏览 ...
- VC 常用资源
vckbase:www.vckbase.com emule:http://sourceforge.net/projects/emule/files/eMule/ firefox developer:h ...
- Codeforces Round #426 (Div. 2)A题&&B题&&C题
A. The Useless Toy:http://codeforces.com/contest/834/problem/A 题目意思:给你两个字符,还有一个n,问你旋转n次以后从字符a变成b,是顺时 ...
- swift tableViewController
tableViewController 控制器 import UIKit class ViewController: UITableViewController { ...
- Win7环境下 IIS配置
一.介绍IIS Internet Information Services(IIS,互联网信息服务),是由微软公司提供的基于运行Microsoft Windows的互联网基本服务.最初是Windows ...
- Spatial convolution
小结: 1.卷积广泛存在与物理设备.计算机程序的smoothing平滑.sharpening锐化过程: 空间卷积可应用在图像处理中:函数f(原图像)经过滤器函数g形成新函数f-g(平滑化或锐利化的新图 ...
- python学习笔记(二)— 集合
s = set()#建立空的集合 s2 = {'}#没有:的为集合,集合天生去重 s3 = {'} #集合是也是无序的 # s2.add('a')#添加值 # s2.remove('2')#删除值 # ...
- CF #301 E:Infinite Inversions(逆序数,树状数组)
A-Combination Lock B-School Marks C-Ice Cave D-Bad Luck Island E-Infinite Inversions E:Infini ...
- redis哨兵集群、docker入门
redis-sentinel主从复制高可用 Redis-Sentinel Redis-Sentinel是redis官方推荐的高可用性解决方案,当用redis作master-slave的高可用时,如果m ...