今天下午写篇博客吧,分析分析c语言中函数调用的本质,首先我们知道c语言中函数的本质就是一段代码,但是给这段代码起了一个名字,这个名字就是他的的这段代码的开始地址 这也是函数名的本质,其实也就是汇编中的标号.下面我们会接触到一些东西 比如 eip 就是我们常常说的程序计数器,还有ebp和esp (这里是俩个指针,记得我们以前学8086也就一个sp堆栈指针)分别为EBP是指向栈底的指针,在过程调用中不变,又称为帧指针.ESP指向栈顶,程序执行时移动,ESP减小分配空间,ESP增大释放空间,ESP又称…
某天,王尼玛写了段C程序: #include <stdio.h> void input() { int i; ]; ; i < ; i++) { array[i] = i; } } void output() { int i; ]; ; i < ; i++) { printf("%d\n", array[i]); } } int main() { input(); output(); ){} ; } 这段代码的目的很简单,在input函数中定义了array[20…
数据类型可以理解为固定内存大小的别名.比如int类型,就是表示占用4字节的内存. 1 数据类型的大小 用sizeof操作符获得数据类型的大小. 比如 int a[5];   sizeof(a)就可以得出int型数组a的大小是20字节, sizeof(*a)可以得出int型数组a的指针大小是4字节. 不同数据类型占据内存空间不一样,写代码测试: int main() { int a[10]; printf("a: %d, a+1: %d, &a: %d, &a+1:%d \n&qu…
数据类型决定长度的含义:我们一个内存地址(0x30000000),本来这个地址只代表1个字节的长度,但是实际上我们可以通过给他一个类型(int),让他有了长度(4),这样这个代表内存地址的数字(0x30000000)就能表示从这个数字(0x30000000)开头的连续的n(4)个字节的内存格子了(0x30000000 + 0x30000001 + 0x30000002 + 0x30000003). 数据类型决定解析方法的含义:譬如我有一个内存地址(0x30000000),我们可以通过给这个内存地…
ps:先做草稿,以后有时间再整理并贴图,:) 主要是利用栈底寄存器(ebp).栈顶寄存器(esp)跟eax寄存器(存储返回值)来实现. 假设P调用Q: P() { Q(1,2); } (跟实际情况可能有点差异,主要还是用来了解函数调用的过程) 1.调用前准备,将Q的参数放到栈中(非push) mov $1, (%esp) mov $2, 4(%esp) 2.调用call 0x12345678 (Q的地址) 首先将函数的返回地址(call语句后的那条指令的地址)进栈, 然后跳到0x12345678…
➠更多技术干货请戳:听云博客 基本术语定义 1.系统栈(system stack)是一个内存区,位于进程地址空间的末端. 2.在将数据压栈时,栈是自顶向下增长的,该内存区用于函数的局部变量提供内存.它也支持在调用函数时传递参数. 3.如果调用了嵌套的过程,栈会自上而下增长,并接受新的活动记录(activation record)来保存一个过程所需的所有数据. 4.当前执行过程的活动记录,由标记顶部位置的帧指针(frame point)和标记底部位置的栈指针(stack point)定义. 5.在…
#################################                              ##       基本知识               ##                              ################################# 当然我们一切都是从最简单的内建类型开始,最后我会做一些推广.先看一下基本的形式,我们从这里起步! --------------指针---------------- int a=10; i…
目录 简介 重排序 写的内存屏障 非lock和LazySet 读的性能 总结 简介 Volatile关键字对熟悉java多线程的朋友来说,应该很熟悉了.Volatile是JMM(Java Memory Model)的一个非常重要的关键词.通过是用Volatile可以实现禁止重排序和变量值线程之间可见两个主要特性. 今天我们从汇编的角度来分析一下Volatile关键字到底是怎么工作的. 重排序 这个世界上有两种重排序的方式. 第一种,是在编译器级别的,你写一个java源代码,经过javac编译之后…
目录 简介 一个普通的virtual call 普通方法中的null check 反优化的例子 总结 简介 之前我们在讲Virtual call的时候有提到,virtual call方法会根据传递的参数实例的不同而进行优化,从而优化成为classic call,从而提升执行效率. 今天我们考虑一下,在virtual call中执行nullcheck的时候,如果已经知道传递的参数是非空的.JIT会对代码进行优化吗? 一起来看看吧. 一个普通的virtual call 我们来分析一下在方法中调用li…
来源: wjlkoorey 链接:http://blog.chinaunix.net/uid-23069658-id-3981406.html 本文主要从进程栈空间的层面复习一下C语言中函数调用的具体过程,以加深对一些基础知识的理解. 先看一个最简单的程序: 主函数main里定义了4个局部变量,然后调用同文件里的foo1()函数.4个局部变量毫无疑问都在进程的栈空间上,当进程运行起来后我们逐步了解一下main函数里是如何基于栈实现了对foo1()的调用过程,而foo1()又是怎么返回到main函…