简单的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 ...
随机推荐
- Codeforces1379-题解
很久以前,申蛤申请了一个cf号叫 wzxakioi 有一天,戌蛤带着申蛤用这个账号打了一场div3,然后它的rating超过了shzr 之后申蛤又用这个号打了三场div2,于是 CF1379C 题意 ...
- python匿名函数和内置函数
一.匿名函数 匿名函数定义lambda a,b,c:(x,y,z) a.b.c相当于形参,多个形参之间用逗号隔开,多个形参不能用括号括起来 (x.y.z)相当于返回值,多个返回值之间用逗号隔开,多个返 ...
- Android实现QQ登录
https://www.jianshu.com/p/e59bc198e88f
- 统计一个16位二进制数中1的个数,并将结果以十六进制形式显示在屏幕上,用COM格式实现。
问题 统计一个16位二进制数中1的个数,并将结果以十六进制形式显示在屏幕上,用COM格式实现. 代码 code segment assume cs:code org 100h main proc ne ...
- PHP xml_set_object() 函数
定义和用法 xml_set_object() 函数允许在对象中使用 XML 解析器.高佣联盟 www.cgewang.com 如果成功,该函数则返回 TRUE.如果失败,则返回 FALSE. 语法 x ...
- Skill 解决 Design Library 被识别成 Technology Library 的问题
https://www.cnblogs.com/yeungchie/ code procedure(ycTechLibToDesign(libName attachLibName) prog((lib ...
- luogu P5473 [NOI2019]I 君的探险 交互 随机 二分 分治 整体二分
LINK:I 君的探险 神仙题! 考虑一个暴力的做法 每次点亮一个点 询问全部点 这样询问次数为 \(\frac{n\cdot (n-1)}{2}\) 可以通过前5个点. 考虑都为A的部分分 发现一个 ...
- 【NOIP2016】天天爱跑步 题解(LCA+桶+树上差分)
题目链接 题目大意:给定一颗含有$n$个结点的树,每个结点有一个权值$w$.给定$m$条路径,如果一个点与路径的起点的距离恰好为$w$,那么$ans[i]++$.求所有结点的ans. 题目分析 暴力的 ...
- 实验05——java算术运算符减法
package cn.tedu.demo; import java.math.BigDecimal; /** * @author 赵瑞鑫 E-mail:1922250303@qq.com * @ver ...
- 解决Vue中element-ui输入框无法输入问题
<el-input placeholder="请输入内容" v-model="input3" class="input-with-select& ...