X86汇编代码分析-函数调用
1)
int add(int i, int j)
{return i + j;
}int main()
{int a = 1;int b = 7;a = add(a, b);printf("%d\n",a);
}
汇编代码:
.file "ex3.c".text.globl add.type add, @function
add:
.LFB0:.cfi_startprocpushq %rbp # rbp入栈, 把rbp里的值压入堆栈。即当前rsp-4出的值变为rbp的值,rbp本身的值不变。.cfi_def_cfa_offset 16.cfi_offset 6, -16movq %rsp, %rbp # rsp 的值给rbp.cfi_def_cfa_register 6movl %edi, -4(%rbp) # edi 给rbp地址-4, 1movl %esi, -8(%rbp) # esi 给rbp地址-8, 7movl -4(%rbp), %edx # 又把1 给 edxmovl -8(%rbp), %eax # 又把7 给 eax
# movl $1, %edx # 又把1 给 edx
# movl $7, %eax # 又把7 给 eaxaddl %edx, %eax # eax=eax+edxpopq %rbp # 是把当esp指向的栈中的值(即之前push rbp进栈的rbp的值)赋给rbp
# 并且esp+4(dx的值改变,esp在pop之前指向的地方的值不变,还是之前ax进栈后的值,即堆栈里的那个值不会自动清零) .cfi_def_cfa 7, 8ret.cfi_endproc
.LFE0:.size add, .-add.section .rodata
.LC0:.string "%d\n".text.globl main.type main, @function
main:
.LFB1:.cfi_startprocpushq %rbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movq %rsp, %rbp.cfi_def_cfa_register 6subq $16, %rsp # 为什么知道是16 byte?
# movl $1, -8(%rbp) # 第1个参数movl $1, 8(%rsp)
# movl $7, -4(%rbp) # 第2个参数movl $7, 12(%rsp)movl -4(%rbp), %edx # 把7给edxmovl -8(%rbp), %eax # 把1给eaxmovl %edx, %esi # edx 给esi, 7, 不是什么变址寄存器啊movl %eax, %edi # eax 给edi, 1call add
# movl %eax, -8(%rbp)
# movl -8(%rbp), %eaxmovl %eax, %esileaq .LC0(%rip), %rdi
# movl $0, %eaxcall printf@PLTmovl $0, %eaxleave.cfi_def_cfa 7, 8ret.cfi_endproc
.LFE1:.size main, .-main.ident "GCC: (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0".section .note.GNU-stack,"",@progbits
大部分看得懂,小部分不知道什么意思。汇编是可以修改的,跟C语言差不多。
感觉Fortran更加麻烦一些。
.file "b3.frac.f90".text.p2align 4,,15.globl frac_.type frac_, @function
frac_:
.LFB0:.cfi_startproc# frac(k,gij,b,u,i,j)movl (%rdi), %r10d # k, 第一个参数。r10d为r10的低32位,因为k是整数movsd (%rsi), %xmm0 # gij, 第2个参数,加载到xmm0的低64位。testl %r10d, %r10d # test只是进行按位与,不进位。判断k是否为0。jle .L10 # 算是一个技巧性的预处理,如果k==0,就直接结束。确实有为0的。pushq %r12 # 被调用者保存.cfi_def_cfa_offset 16.cfi_offset 12, -16pushq %rbp # 被调用者保存.cfi_def_cfa_offset 24.cfi_offset 6, -24leal 1(%r10), %r11d pushq %rbx.cfi_def_cfa_offset 32.cfi_offset 3, -32movslq (%r9), %raxmovslq %r10d, %r9imulq $1681, %r9, %rbxmovslq (%r8), %r12leaq (%rax,%rax,4), %rdileaq (%rax,%rdi,8), %rbpleaq (%rbx,%rbp), %rdiaddq %r12, %rdicmpl $2, %r10dleaq (%rcx,%rdi,8), %raxjle .L6movsd (%rax), %xmm2leaq 0(%rbp,%r12), %raxmovl $3, %ediaddq %rbx, %raxsalq $3, %raxleaq -53792(%rcx,%rax), %rbxleaq -26896(%rcx,%rax), %r8leal -3(%r10), %eaxshrl %eaximulq $26896, %rax, %raxsubq %rax, %rbx.p2align 4,,10.p2align 3
.L4:movsd 13448(%r8), %xmm3subq $26896, %r8movslq %edi, %raxmovapd %xmm3, %xmm1subsd %xmm2, %xmm1movsd 26896(%r8), %xmm2mulsd -16(%rdx,%rdi,8), %xmm1addsd %xmm1, %xmm0movapd %xmm2, %xmm1subsd %xmm3, %xmm1mulsd -8(%rdx,%rdi,8), %xmm1addq $2, %rdicmpq %rbx, %r8addsd %xmm1, %xmm0jne .L4
.L3:movq %r9, %rdimovslq %r11d, %r11addq %r12, %rbpsubq %rax, %rdiimulq $1681, %rdi, %rdiimulq $13448, %r11, %r11imulq $-13448, %r9, %r8addq %rdi, %rbpleaq (%rcx,%rbp,8), %rcx.p2align 4,,10.p2align 3
.L5:movsd (%rcx), %xmm1leaq (%rcx,%r11), %rdisubq $13448, %rcxsubsd (%rdi,%r8), %xmm1mulsd (%rdx,%rax,8), %xmm1addq $1, %raxcmpl %eax, %r10daddsd %xmm1, %xmm0jge .L5popq %rbx.cfi_def_cfa_offset 24popq %rbp.cfi_def_cfa_offset 16movsd %xmm0, (%rsi)popq %r12.cfi_def_cfa_offset 8ret.p2align 4,,10.p2align 3
.L10:.cfi_restore 3.cfi_restore 6.cfi_restore 12rep ret.p2align 4,,10.p2align 3
.L6:.cfi_def_cfa_offset 32.cfi_offset 3, -32.cfi_offset 6, -24.cfi_offset 12, -16movl $1, %eaxjmp .L3.cfi_endproc
.LFE0:.size frac_, .-frac_.ident "GCC: (Ubuntu 7.4.0-1ubuntu1~18.04.1) 7.4.0".section .note.GNU-stack,"",@progbits
X86汇编代码分析-函数调用相关推荐
- 反汇编代码分析--函数调用
C++反汇编代码分析--函数调用 代码如下: #include "stdlib.h" int sum(int a,int b,int m,int n) { return a+b ...
- C++反汇编代码分析--函数调用
推荐阅读: C++反汇编代码分析–函数调用 C++反汇编代码分析–循环结构 C++反汇编代码分析–偷调函数 走进内存,走进汇编指令来看C/C++指针 代码如下: #include "stdl ...
- Linux内核汇编代码分析
Linux内核汇编代码分析 1.vmlinux.lds.S文件分析 1.2 vmlinux.lds.S文件总体框架 1.3 代码段 1.4 只读数据段 1.5 init段 1.6 数据段 1.7 未初 ...
- x86汇编代码转x64平台使用(VS2010测试通过)最简单的方法
众所周知,在x86平台,可以直接使用__asm 内嵌汇编代码,然而在x64平台却不行了. 现在解决这个问题. 一.VS中创建控制台程序,改成x64平台启动. 二.创建test.asm文件.将原先的汇编 ...
- C++ 汇编代码分析——递归函数调用、浮点数比较、选择语句
环境ubuntu 18.04 LTS 课程地址:https://www.icourse163.org/course/NJU-1001625001 一.递归过程调用 示例程序,这是一个简单的递归加法. ...
- linux内核nasm,在x86汇编代码,NASM,Linux中操作字符串
我一直在试图操纵我的.s文件中的一个字符串 我希望将包含"/ bin / bash"的变量"pa"转换为"/ bin / sh",然后我想调 ...
- 【Android 逆向】x86 汇编 ( call 子函数调用指令 | jmp 跳转指令 | lea 加载指令 | mov 数据传送指令 )
文章目录 一.call 子函数调用指令 二.jmp 跳转指令 三.lea 加载指令 四.mov 数据传送指令 总结 一.call 子函数调用指令 call 指令是 子函数调用指令 , 调用的指令的下一 ...
- 寄存器(1)寄存器概念,x86寄存器种类说明及汇编代码详解
寄存器(1)寄存器概念,x86寄存器种类说明及汇编代码详解 1. 什么是寄存器 1.1 概念 1. 什么是寄存器: 2. 寄存器作用: 1.2 通俗易懂理解寄存器 2. x86寄存器种类说明及汇编代码 ...
- 【Android 逆向】x86 汇编 ( 使用 IDA 解析 x86 架构的动态库文件 | x86 汇编语言分析 )
文章目录 一.x86 汇编语言分析 一.x86 汇编语言分析 在上一篇博客 [Android 逆向]x86 汇编 ( 使用 IDA 解析 x86 架构的动态库文件 | 使用 IDA 打开动态库文件 | ...
最新文章
- 无需精通编程:走进人工智能比你想象中容易
- div css图片列表实例
- java上传文件到ftp_java实现文件上传下载至ftp服务器
- 第三章 springboot + jedisCluster(转载)
- webpack--安装,使用
- atitit.php 流行框架 前三甲为:Laravel、Phalcon、Symfony2 attilax 总结
- LaTeX报错 Difference (2) between bookmark levels is greater (hyperref)	than one, level fixed.
- Python学习第一弹——Python环境搭建
- php获取用户手机imei id,获取手机设备信息 IMEI
- 线对 Line pairs度量空间频率
- 计算机技术员自我介绍,技术员的自我介绍范文
- GNU Screen的使用方法
- java实现手动派单,一种智能并单及派单方法与流程
- 三万文字透视前瞻:区块链及隐私计算在传统企业中的技术认知与进阶思考
- linux学习好文章,好网站
- 我国计算机的最新进展,我国计算机最新进展
- 36Kr常锋无人机-项目分析和投资决策要点
- uni-app实现锚点定位功能
- RFID射频卡写入手机NFC心路小记
- 微信公众平台开放改名了 附修改公众号名称方法
热门文章
- javascript - 实现拍照功能(详细示例代码)
- WiFi共享精灵在使用时出现的错误代码1的解决方法
- 局部响应归一化(Local Response Normalization,LRN)和批量归一化(Batch Normalization,BN)的区别
- matlab实验函数编写与程序设计,实验二MATLAB程序设计.doc
- c语言sprintf函数 long,基于C语言sprintf函数的深入理解
- 华为android9升级名单,华为EMUI9.0流畅度大提升,更新内容和升级名单汇总
- Qt事件循环的一些理解
- web前端工程师面试题手册(2022最新版基础、核心、进阶)
- mac下每次打开ppt弹出自动保存的文件
- 一文看懂目标检测之RCNN(NMS和Soft-NMS算法)