column函数用法详解,100个pandas函数详解

在理解函数堆栈帧之前,您需要了解基础概念。 首先,请参阅博客以了解程序在编译阶段发生的操作。 程序环境和预处理

总而言之,编译过程的最终产品是可执行程序——由一系列机器语言指令组成。 当程序运行时,操作系统将这些指令加载到计算机的内存中,所以在生成每条指令都有特定的内存地址可执行程序时,程序变成机器识别的二进制代码。 还有,我需要知道内存的分区。

我们今天讨论的函数堆栈帧主要在堆栈区域进行。 以及栈区的结构是从高地址到低地址开辟空间

我知道一些组件的基本符号。

基本寄存器:

esp:总是指堆栈顶部空间

ebp:用于在堆栈中记录地址,始终指向系统堆栈顶部堆栈帧的底部

eax/ebx/ecx/edx:这些寄存器就像容器,存储一些值,知道一些汇编的指令。

1. mov esp,ebp这里的mov是指将ebp的值代入esp ——,即右边的值代入左边

2. pop edi这里是将栈顶元素先栈,然后分配给寄存器edi

3 .推送ecx这里是将ecx的值推入堆栈顶部

4. dword ptr [地址]表示该地址所指向的4字节数据,

5. rep stos dword ptr es:[edi]表示eax覆盖从edi开始的内存,edi减少4。 循环ecx次。

6. sub esp,0E4h此处是esp减去0E4h (十六进制)

选择相对简单的函数调用,以便从程序集级别观察函数堆栈区域上方的创建。

#includestdio.hintadd(intx,int y ) {return x y; (}int main ) ) {int a=10; int b=20; int c=0; c=add(a,b ); 返回0; }调试函数,转移到反汇编

这就是add函数的汇编代码。 按如下方式逐步解读。

http://www.Sina.com /这里首先将ebp推入堆栈。 此时,esp也指向ebp,因为esp始终指向堆栈的顶部。 将http://www.Sina.com/esp的值代入ebp中,因此ebp也指向堆栈的顶部

http://www.Sina.com/:将esp减去0E4h,即0e4hhttp://www.Sina.com/:EBX、esi和edi这三个值推入堆栈。 因为esp总是指向栈顶330,所以必须一个接一个地上升

将-http://www.Sina.com/寄存器ecx 第一步:寄存器eax http://www.Sina.com/0 ccccccccch写入寄存器EAXhttp://www.Sina.com/

因为保存在edi中的存储器地址为ebp-0E4h,0E4h的十进制值为228,周期数ecx 39h为十进制的57。 但是,由于228是57的4倍,因此该命令意味着将从ebp到ebp-0E4h的每4个字节的空格复制到eax的值,即0 ccccccccccccch

这里填充中央没有保存的cc cc cc cc,实际上是我们有时访问内存越界时看到的打孔烫发…

将0Ah代入-http://www.Sina.com/:ebp-8的位置,在10进制10或a值http://www.Sina.com/:ebp-14h的位置,输入14h10进制20或b值http://ww.Sina

http://www.Sina.com/:前两行首先将ebp-14h的值压入寄存器eax,后两行首先将ebp-8h的值压入寄存器ecx,然后将ecx压入堆栈

这里称为函数参数,它将函数传递给所创建的临时变量。

这里调用add函数。 call是访问add所在存储器的地址。 但是,需要注意的是,在add访问某个函数的地址时,从第二步:

按f11键访问函数内部

跳转到函数的代码汇编

现在开始访问add函数的内部!

此函数的堆栈帧与创建main函数时的堆栈帧相同,因此这里省略了创建函数堆栈帧的具体步骤

这是

里寄存器 esp 和 ebp之间所夹的区域为add的函数栈帧

– ❤️ 第一步: 将 ebp+8 所指向的值,(也就是传进来的形参10) 存入寄存器eax中第二步:将ebp-0Ch 所指向的值,(也就是传进来的形参20) 与寄存器eax相加,这时寄存器eax存储的就是30
– ❤️ 第一步: 这里分别将寄存器edi esi ebx 出栈第二步:将esp的地址加上0C0h ,也就是在初始化的时候esp减去的大小,所以这时esp和ebp指向同一块空间

– ❤️ 第一步:将ebp的值赋给esp第二部 :将栈顶的元素弹出,并赋给ebp,注意:这里栈顶存的ebp实际上是main函数栈帧ebp所指向的ebp的地址

– ❤️ 这时进行到了return ,也就是add函数执行完成,返回main函数

但是返回main函数并不知道从哪个指令开始执行,所以这里就体现了—将call下一条指令存入函数栈帧的作用,使得调用函数结束之后依然能找到下一条指令,事实也是如此:
– ❤️ 第一步:将esp的地址加上8,由于每个都是四字节,也就是向下移动两位第二步:将eax也就是我们在add里得到的返回值,赋值给ebp-20h 也就是c所在的地址空间

第二步将返回值成功的带回了主函数!
– ❤️

后面对于main函数的销毁和 对于add的销毁是一模一样的 ,这里就不在赘述了

总结:

函数栈帧让我们充分的意识到函数建立的过程包括:

函数的形参是如何传递进函数:在函数栈帧上拷贝给一个临时变量返回值是如何传递回主函数的:由一个寄存器储存带回主函数,与形参 和 函数内创建的临时变量无关(出函数就会被销毁)

Published by

风君子

独自遨游何稽首 揭天掀地慰生平

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注