X86-64寄存器和栈帧 概要 说到x86-64,总不免要说说AMD的牛逼,x86-64是x86系列中集大成者,继承了向后兼容的优良传统,最早由AMD公司提出,代号AMD64:正是由于能向后兼容,AMD公司打了一场漂亮翻身战.导致Intel不得不转而生产兼容AMD64的CPU.这是IT行业以弱胜强的经典战役.不过,大家为了名称延续性,更习惯称这种系统结构为x86-64. X86-64在向后兼容的同时,更主要的是注入了全新的特性,特别的:x86-64有两种工作模式,32位OS既可以跑在传统模式中,…
简介 通用寄存器可用于传送和暂存数据,也可参与算术逻辑运算,并保存运算结果.除此之外,它们还各自具有一些特殊功能.通用寄存器的长度取决于机器字长,汇编语言程序员必须熟悉每个寄存器的一般用途和特殊用途,只有这样,才能在程序中做到正确.合理地使用它们. 16位cpu通用寄存器共有 8 个:AX,BX,CX,DX,BP,SP,SI,DI. 八个寄存器都可以作为普通的数据寄存器使用. 但有的有特殊的用途:AX为累加器,CX为计数器,BX,BP为基址寄存器,SI,DI为变址寄存器,BP还可以是基 指针,S…
栈帧(stack frame)是在程序的运行时栈中分配的内存块,用于特定的函数调用 如果一个函数没有执行则不需要内存,当函数被调用时就需要用到内存 1.传给函数的参数的值需要存储到函数能够找到它们的位置 2.函数在执行过程中可能需要临时的存储空间,通过声明局部变量来分配这类临时空间,这些变量在函数内部使用,函数调用完后,就无法再访问它们 在将控制权转交给函数之前,编译器会插入代码,将函数参数放入栈帧内,并分配足够的内存,以保存函数的局部变量 函数的返回地址也存储在新的栈帧内 使用栈帧使得递归成为…
在x86的计算机系统中,内存空间中的栈主要用于保存函数的参数,返回值,返回地址,本地变量等.一切的函数调用都要将不同的数据.地址压入或者弹出栈.因此,为了更好地理解函数的调用,我们需要先来看看栈是怎么工作的. 栈是什么? 简单来说,栈是一种LIFO形式的数据结构,所有的数据都是后进先出.这种形式的数据结构正好满足我们调用函数的方式:父函数调用子函数,父函数在前,子函数在后:返回时,子函数先返回,父函数后返回.栈支持两种基本操作,push和pop.push将数据压入栈中,pop将栈中的数据弹出并存…
栈帧 栈帧和指针可以说是C语言的精髓.栈帧是一种特殊的数据结构,在C语言函数调用时,栈帧用来保存当前函数的父一级函数的栈底指针,当前函数的局部变量以及被调用函数返回后下一条汇编指令的地址.如下图所示: 栈帧位于栈内存中,接下里我们用一个实例展示一下栈帧的入栈和退栈过程. stackframe.c #include <stdio.h> int func(int m, int n) { return m+n; } int main() { int m = 8; int n = 6; func(m,…
栈帧(stack frame),机器用栈来传递过程参数,存储返回信息,保存寄存器用于以后恢复,以及本地存储.为单个过程(函数调用)分配的那部分栈称为栈帧.栈帧其实是两个指针寄存器, 寄存器%ebp为帧指针,而寄存器%esp为栈指针,当程序运行时,栈指针可以移动(大多数的信息的访问都是通过帧指针的).总之简单一句话,栈帧的主要作用是用来控制和保存一个过程的 所有信息的.栈帧结构如下所示: 下面,我们通过一个简单的程序来了解栈帧: 简单的函数分析,如下图: 该函数的栈帧情况: 当*p=bug,修改栈…
从汇编的角度解析函数调用过程 看看下面这个简单函数的调用过程: int Add(int x,int y) { ; sum = x + y; return sum; } int main () { ; ; ; ret = Add(a,b); ; } 今天主要用汇编代码去讲述这个过程,首先介绍几个寄存器和简单的汇编指令的意思. 先看几个函数调用过程涉及到的寄存器: (1)esp:栈指针寄存器(extended stack pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶…
转载自地址:http://blog.csdn.net/zsy2020314/article/details/9429707       今天突然想分析一下函数在相互调用过程中栈帧的变化,还是想尽量以比较清晰的思路把这一过程描述出来,关于c函数调用原理的理解是很重要的. 1.关于栈 首先必须明确一点也是非常重要的一点,栈是向下生长的,所谓向下生长是指从内存高地址->低地址的路径延伸,那么就很明显了,栈有栈底和栈顶,那么栈顶的地址要比栈底低.对x86体系的CPU而言,其中 ---> 寄存器ebp(…
之前多次提到接触到调用JavaCalls::call()方法来执行Java方法,如: (1)Java主类装载时,调用JavaCalls::call()方法执行的Java方法checkAndLoadMain()方法 (2)类的初始化过程中,调用JavaCalls::call()方法执行的Java方法<clinit>方法 可以看出,JavaCalls::call()方法为虚拟机调用Java方法提供了便利,Java虚拟机有invokestatic.invokedynamic.invokestatic…
在前一篇 第4篇-JVM终于开始调用Java主类的main()方法啦 介绍了通过callq调用entry point,不过我们并没有看完generate_call_stub()函数的实现.接下来在generate_call_stub()函数中会处理调用Java方法后的返回值,同时还需要执行退栈操作,也就是将栈恢复到调用Java方法之前的状态.调用之前是什么状态呢?在 第2篇-JVM虚拟机这样来调用Java主类的main()方法 中介绍过,这个状态如下图所示. generate_call_stub…