简单的main方法调用一个加减法函数背后的细节
测试程序
/*
* AddTest.c
*
* Created on: 2019年10月13日
* Author: appweb
*/
#include <stdio.h>
int add(int a, int b) {
int c = addAgain(a, b);
return c;
}
int addAgain(int a, int b) {
int c = a + b;
return c;
}
int sub(int a, int b) {
int c = a - b;
return c;
}
int main() {
int s = add(5, 3);
int d = sub(5, 3);
return 0;
}
makefile
PROJECT_ROOT = $(dir $(abspath $(lastword $(MAKEFILE_LIST))))
OBJS = AddTest.o
# 如果在命令行直接执行make 需要export BUILD_MODE=debug 或者run
ifeq ($(BUILD_MODE),debug)
CFLAGS += -g
else ifeq ($(BUILD_MODE),run)
CFLAGS += -O2
else
$(error Build mode $(BUILD_MODE) not supported by this Makefile)
endif
all: InvokeFunction
# $@ 表示规则中的目标文件集。在模式规则中,如果有多个目标,那么,"$@"就是匹配于目标中模式定义的集合。
# $^ 所有的依赖目标的集合。以空格分隔。如果在依赖目标中有多个重复的,那个这个变量会去除重复的依赖目标,只保留一份。
# $< 依赖目标中的第一个目标名字。如果依赖目标是以模式(即"%")定义的,那么"$<"将是符合模式的一系列的文件集。注意,其是一个一个取出来的。
# $? 所有比目标新的依赖目标的集合。以空格分隔。
# 输出变量可以使用如下办法
$(info $$OBJS is [${OBJS}])
$(info $$(CXX) is [$(CXX)])
$(info $$(PROJECT_ROOT) is [$(PROJECT_ROOT)])
AddTest: $(OBJS)
$(CXX) -o $@ $^
%.o: $(PROJECT_ROOT)src/%.c
$(CXX) -c $(CFLAGS) $(CXXFLAGS) $(CPPFLAGS) -o $@ $<
clean:
rm -fr AddTest $(OBJS)
一如既往的使用CDT,寄存器监视(我需要观察的几个)、内存监视 、反编译的汇编指令窗口弄在一起,调试起来真是方便
打包好的工程
先编译下然后开始调试并观察

开始调试


添加寄存器监视

添加内存监视


启用指令单步调试


rsp是栈顶,rbp是栈底,大小及栈分配的生长方向如下:
栈分配生长方向
<-------------------------------------+
rsp 栈顶 rbp 栈底
+------------------+------------------+
| | |
| | |
+------------------+------------------+
内存低位地址 内存高位地址
现在rsp是0xfffffffd750,执行完下图的
00000000000004195598: mov %rsp,%rbp
00000000000004195601: sub $0x10,%rsp
这两条汇编指令后,rbp是0xfffffffd750,rsp是0xfffffffd740,这就是 函数栈帧空间分配





在执行完callq与push指令之后,栈顶再往前的内存(就是紧靠着栈顶比栈顶还小的内存)会发生变化,看图中内存监视器红色部分,按有些书上说法此处是保存了rip和rbp,但是我没能太理解,看数值不怎么能对上

注意看 进入addAagin方法后,并不是像某些书上说的会分配函数栈帧控空间,我猜测是编译器做了优化吧,因为addAagin方法不再调用其他方法了。
看了R大的文章,这种函数应该是 叶函数,叶函数是不调用别的函数的函数。


00000000000004195547: mov %edi,-0x14(%rbp)
00000000000004195550: mov %esi,-0x18(%rbp)
看上图,从edi和esi集群器向 相对于rbp(栈底)偏移(负偏移)的内存传数据,这个称之为压栈
不过有些书上讲的是 向 相对rsp(栈顶)偏移(正偏移)的内存传数据,我理解成一个意思,不过是内存定位的方式不同罢了























简单的main方法调用一个加减法函数背后的细节的更多相关文章
- [Inside HotSpot] hotspot的启动流程与main方法调用
hotspot的启动流程与main方法调用 虚拟机的使命就是执行public static void main(String[])方法,从虚拟机创建到main方法执行会经过一系列流程.这篇文章详细讨论 ...
- 【M12】了解“抛出一个exception”与“传递一个参数”或“调用一个虚函数”之间的差异
1.方法参数的声明语法和catch语句的语法是一样的,你可能会认为主调方法调用一个方法,并向其传递参数,与抛出一个异常传递到catch语句是一样的,是的,有相同之处,但也有更大的不同. 2.主调方法调 ...
- 从一个简单的main方法执行谈谈JVM工作机制
本来JVM的工作原理浅到可以泛泛而谈,但如果真的想把JVM工作机制弄清楚,实在是很难,涉及到的知识领域太多.所以,本文通过简单的mian方法执行,浅谈JVM工作原理,看看JVM里面都发生了什么. 先上 ...
- python+selenium之中类/函数/模块的简单介绍和方法调用
# coding=utf-8 class ClassA (object): string1 = "这是一个字符串." def instancefunc(self): print ( ...
- 使用main方法调用http请求本地服务器的某个servlet报错问题
java.io.IOException: Server returned HTTP response code: 500 for URL: http://localhost:8081/test/myS ...
- java 主类的main方法调用其他方法
方法1:A a=new test().new A(); 内部类对象通过外部类的实例对象调用其内部类构造方法产生,如下: public class test{ class A{ void fA(){ S ...
- C++调用一个成员函数的需求this指针的情况
1.虚成员函数,因为需要this展望虚表指针的指针 2.在数据成员的操作部件的功能 #include "stdafx.h" #include <iostream> #i ...
- 用Main方法调用freemarker生成文件
MyGenerator.java package com.comp.common; import java.io.BufferedWriter; import java.io.File; import ...
- java本地方法如何调用其他程序函数,方法详解
JNI是Java Native Interface的缩写,中文为JAVA本地调用.从Java 1.1 开始,Java Native Interface (JNI)标准成为java平台的一部分,它允许J ...
随机推荐
- 根据 Promise/A+ 和 ES6 规范,实现 Promise(附详细测试)
Promise 源码 https://github.com/lfp1024/promise promise-a-plus const PENDING = 'PENDING' const REJECTE ...
- 题解 洛谷 P4492 【[HAOI2018]苹果树】
考虑生成一颗二叉树的过程,加入第一个节点方案数为\(1\),加入第二个节点方案数为\(2\),加入第三个节点方案数为\(3\),发现生成一颗\(n\)个节点的二叉树的方案数为\(n!\). 所以题目中 ...
- ISE第三方编辑器的使用
刚开始使用ISE时候感觉ISE自带的编辑器并没有什么难用的,但是在看到了小梅哥的视频教学中那样行云流水般的操作让我心动不已,由此找到了相关的编辑器.为了以后看着方便直接摘取了前人的经验在我自己的博客中 ...
- Python 正则表达式简单了解
match 从字符串的开始匹配 如果开头不符合要求 就会报错 search 用字符串里的每一个元素 去匹配找的元素 1.匹配单个字符 \d 数字 \D 非数字 . 匹配任意字符 除了\n [] ...
- 关于RecyclerView(二)设置EmptyView
首先重写一个RecyclerView类 package com.onepilltest.others; import android.content.Context; import android.s ...
- 性能分析(1)- Java 进程导致 CPU 使用率升高,问题怎么定位?
性能分析小案例系列,可以通过下面链接查看哦 ps:这些分析小案例不能保证百分比正确,是博主学习过程中的总结,仅做参考 前提 本机有一个很占用 CPU 的项目,放在了 Tomcat 下启动着 如何定位 ...
- 性能测试必备知识(7)- 深入理解“CPU 使用率”
做性能测试的必备知识系列,可以看下面链接的文章哦 https://www.cnblogs.com/poloyy/category/1806772.html 回顾 CPU 使用率是单位时间内 CPU 使 ...
- PHP date_timezone_get() 函数
------------恢复内容开始------------ 实例 返回给定 DateTime 对象的时区: <?php$date=date_create(null,timezone_open( ...
- 6.3 省选模拟赛 Decompose 动态dp 树链剖分 set
LINK:Decompose 看起来很难 实际上也很难 考验选手的dp 树链剖分 矩阵乘法的能力. 容易列出dp方程 暴力dp 期望得分28. 对于链的情况 容易发现dp方程可以转矩阵乘法 然后利用线 ...
- ZROI 提高十连测 DAY3
由于我不太会写 觉得从比赛开始就冷静分析.然后看完三道题心态有点爆炸没有紧扣题目的性质. 这个心态是不可取的尽量不要有畏难心理 不要草草的写暴力. LINK:[最长01子序列](http://zhen ...