【工欲善其事,必先利其器】之怎么查看c++代码生成的汇编代码

cpp加油站
• 阅读 2163

本篇文章讲解怎么得到c++代码对应的汇编代码,想要真正的理解一段代码到底是怎么执行的,还是要从汇编的层面去看,那怎么得到一段c++代码所对应的汇编代码呢,下面为你介绍三种方式。

1. gcc编译生成XXX.s文件

一般来讲,给你一个cpp文件,比如test.cpp,然后我们编译都是直接g++ test.cpp这样简单直接的方式,但其实它中间有很多个过程的,包含预处理、编译、链接等过程,而这其中的编译这个过程其实就是生成了汇编文件。

比如对于一个cpp文件,我们执行下列命令:

g++ -E test.cpp -o test.i  #预处理过程
g++ -S test.i -o test.s  #编译过程

这样生成test.s就是test.cpp所对应的汇编代码,当然我们也可以一步到位,直接使用g++ -S test.cpp -o test.s也是可以的。

2. 使用objdump命令得到汇编代码

linux下的objdump命令用于从可执行文件或者目标文件中显示某些信息,所以用它也可以得到可执行文件对应的汇编代码。

比如对于test.cpp,可以使用如下的命令得到汇编指令:

g++ test.cpp -o test
objdump -d test

通过这样的方式能看到可执行文件所对应的汇编指令。

3. 使用gdb命令得到汇编代码

第1、2两种情况下得到的都是编译期间生成的汇编指令,但因为有些代码是运行时才能确定的原因,所以运行时的汇编指令与编译时并不完全一致,比如栈的地址,编译期间其实是不知道的,运行时才会真正的分配。

我们可以使用gdb来获取每一行代码运行时所对应的汇编指令,首先使用g++ -g test.cpp -o test来得到可执行文件,然后gdb ./test进入gdb模式,比如对于这段c++代码:

#include <iostream>
using namespace std;

int main()
{
    int size = 1000;
    size = 10000;
    int arr[size];

    return 0;
}

使用如下gdb命令可得到对应的汇编指令:

(gdb) b main
Breakpoint 1 at 0x4006a4: file test.cpp, line 10.
(gdb) set disassemble-next-line on  #打开汇编指令开关,这样gdb每执行一步,都会打印出来对应执行的汇编指令
(gdb) r
Starting program: /root/a.out 

Breakpoint 1, main () at test.cpp:10
10        return 0;
=> 0x00000000004006a4 <main()+8>:    48 89 e0    mov    %rsp,%rax
   0x00000000004006a7 <main()+11>:    48 89 c1    mov    %rax,%rcx
(gdb) next
6        int size = 1000;
=> 0x00000000004006aa <main()+14>:    c7 45 fc e8 03 00 00    movl   $0x3e8,-0x4(%rbp)
(gdb) 
7        size = 10000;
=> 0x00000000004006b1 <main()+21>:    c7 45 fc 10 27 00 00    movl   $0x2710,-0x4(%rbp)

这样看起问题来就很方便了,我们能看到每一行c++代码对应的汇编指令是什么,对于初学者而言,使用此种方式是最为方便的。

好了,本篇文章就为大家介绍到这里,觉得内容对你有用的话,记得顺手点个赞哦~

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
小万哥 小万哥
7个月前
掌握 C++ 编译过程:面试中常见问题解析
C编译过程C是一种高级编程语言,但是计算机并不能直接理解它。因此,需要将C代码翻译成计算机可以理解的机器语言。这个过程就是编译过程,是C程序从源代码到可执行文件的转换过程,包括预处理、编译、汇编和链接四个阶段。1.预处理在编译器开始编译之前
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Stella981 Stella981
3年前
KVM调整cpu和内存
一.修改kvm虚拟机的配置1、virsheditcentos7找到“memory”和“vcpu”标签,将<namecentos7</name<uuid2220a6d1a36a4fbb8523e078b3dfe795</uuid
Wesley13 Wesley13
3年前
Minix下的汇编
Minix下的汇编大多数的编译器,如TurboC/C,BorlandC/C,M$C/C,GCC,VC,编译过程都是"高级语言""asm""obj".(当然TurboPascal是个例外,它能跳过生成asm文件这一段而直接生成目标代码).Minix下的CC也不例外.一般来说,minix启动时执行的第一段代码就位于mp
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
CMU
一、实验目的1.理解C语言程序的机器级表示。2.初步掌握GDB调试器的用法。3.阅读C编译器生成的x8664机器代码,理解不同控制结构生成的基本指令模式,过程的实现。二、实验工具1.SecureCRT2.Linux3.Objdump命令反汇编4.GDB调试工具
Stella981 Stella981
3年前
Nginx反向代理upstream模块介绍
!(https://oscimg.oschina.net/oscnet/1e67c46e359a4d6c8f36b590a372961f.gif)!(https://oscimg.oschina.net/oscnet/819eda5e7de54c23b54b04cfc00d3206.jpg)1.Nginx反
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这