反汇编看宏函数和函数

通过 gdb 查看程序的汇编代码,比较宏和宏函数的工作效率。

程序汇编代码

程序

例子中的最大值实现,宏和函数逻辑基本相同。宏在源码预编译阶段,被替换为代码,增加了代码的体积;函数多了参数传递,函数进栈和出栈等逻辑,自然资源消耗要比宏多。

  • 测试代码
#define _max(x, y) (x) > (y) ? (x) : (y)

int max_func(int x, int y) {
    return x > y ? x : y;
}
int main() {
    int aaa, bbb, ccc, ddd, eee, mmm;

    aaa = 1;
    bbb = 2;
    eee = 3;
    mmm = 4;
    ccc = max_func(aaa, bbb);
    ddd = _max(aaa, bbb);
    eee = ddd;
}

预编译后,宏被替换为源码。

gcc -E test.cpp -o test.i
int max_func(int x, int y) { return x > y ? x : y; }
int main() {
    int aaa, bbb, ccc, ddd, eee, mmm;

    aaa = 1;
    bbb = 2;
    eee = 3;
    mmm = 4;
    ccc = max_func(aaa, bbb);
    ddd = (aaa) > (bbb) ? (aaa) : (bbb);
    eee = ddd;
}

  • 编译源码为 elf 文件进行 gdb 调试
gcc -g test.cpp -o test
  • 通过 gdb 命令查看程序汇编代码
layout asm

0x4004ed <max_func(int, int)>           push   %rbp
0x4004ee <max_func(int, int)+1>         mov    %rsp,%rbp
0x4004f1 <max_func(int, int)+4>         mov    %edi,-0x4(%rbp)
0x4004f4 <max_func(int, int)+7>         mov    %esi,-0x8(%rbp)
0x4004f7 <max_func(int, int)+10>        mov    -0x4(%rbp),%eax
0x4004fa <max_func(int, int)+13>        cmp    -0x8(%rbp),%eax
0x4004fd <max_func(int, int)+16>        jle    0x400504 <max_func(int, int)+23>
0x4004ff <max_func(int, int)+18>        mov    -0x4(%rbp),%eax
0x400502 <max_func(int, int)+21>        jmp    0x400507 <max_func(int, int)+26>
0x400504 <max_func(int, int)+23>        mov    -0x8(%rbp),%eax
0x400507 <max_func(int, int)+26>        pop    %rbp
0x400508 <max_func(int, int)+27>        retq
0x400509 <main()>                       push   %rbp
0x40050a <main()+1>                     mov    %rsp,%rbp
0x40050d <main()+4>                     sub    $0x20,%rsp
0x400511 <main()+8>                     movl   $0x1,-0x4(%rbp)
0x400518 <main()+15>                    movl   $0x2,-0x8(%rbp)
0x40051f <main()+22>                    movl   $0x3,-0xc(%rbp)
0x400526 <main()+29>                    movl   $0x4,-0x10(%rbp)
0x40052d <main()+36>                    mov    -0x8(%rbp),%edx
0x400530 <main()+39>                    mov    -0x4(%rbp),%eax
0x400533 <main()+42>                    mov    %edx,%esi
0x400535 <main()+44>                    mov    %eax,%edi
0x400537 <main()+46>                    callq  0x4004ed <max_func(int, int)>
0x40053c <main()+51>                    mov    %eax,-0x14(%rbp)
0x40053f <main()+54>                    mov    -0x4(%rbp),%eax
0x400542 <main()+57>                    cmp    -0x8(%rbp),%eax
0x400545 <main()+60>                    jle    0x40054c <main()+67>
0x400547 <main()+62>                    mov    -0x4(%rbp),%eax
0x40054a <main()+65>                    jmp    0x40054f <main()+70>
0x40054c <main()+67>                    mov    -0x8(%rbp),%eax
0x40054f <main()+70>                    mov    %eax,-0x18(%rbp)
0x400552 <main()+73>                    mov    -0x18(%rbp),%eax
0x400555 <main()+76>                    mov    %eax,-0xc(%rbp)
0x400558 <main()+79>                    mov    $0x0,%eax
0x40055d <main()+84>                    leaveq
0x40055e <main()+85>                    retq

汇编知识

测试中出现的汇编知识。

寄存器

寄存器 描述
rbp 64 bit 栈基址寄存器---指向栈底顶
ebp 32 bit 栈基址寄存器---指向栈底
bp 16 bit 栈基址寄存器---指向栈底
rsp 64 bit 栈寄存器---指向栈顶
esp 32 bit 栈寄存器---指向栈顶
sp 16 bit 栈寄存器---指向栈顶
eax 32 bit 通用寄存器
rip 64 bit 地址偏移寄存器

汇编指令

命令 描述
jmp 无条件段内直接转移指令
sub 减法指令
jle 条件转移指令
mov 传送指令
cmp 比较指令
push 进栈指令
pop 出栈指令
ret 段内过程返回指令,使子程序结束,继续执行主程序
callq 相当于 pushq %rip; jmpq addr
leaveq 相当于 movq %rbp; %rsp popq %rbp
retq 相当于 popq %rip

callq,leaveq,retq 中的q是指64位操作数


引用


更精彩内容,请关注我的博客:wenfh2020.com

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 王爽汇编全书知识点大纲 第一章 基础知识 机器语言 汇编语言的产生 汇编语言的组成 存储器 cpu对存储器的读写 ...
    2c3ba901516f阅读 2,629评论 0 1
  • Exercise 3 方法:打开终端运行make qemu-gdb,再打开另一个终端运行make gdb,通过b ...
    找不到工作阅读 10,286评论 0 6
  • 1.地址总线,数据总线,控制总线在哪里,它们有什么作用?答:它们都是cpu连接外部组件的线路。地址总线:地址总线A...
    MagicalGuy阅读 1,657评论 0 1
  • 0. 引言 如果你学的第一门程序语言是C语言,那么下面这段程序很可能是你写出来的第一个有完整的 “输入---处理-...
    pandolia阅读 14,386评论 13 27
  • 计算机系统漫游 代码从文本到可执行文件的过程(c语言示例):预处理阶段,处理 #inlcude , #defin...
    willdimagine阅读 3,790评论 0 5

友情链接更多精彩内容