C语言新手入门理解:函数栈帧——从汇编代码理解函数是如何创建、调用、销毁以及一些基础汇编指令的详细介绍。

(声明:以下均为个人理解陈述,如有错误,还请指出)


在这里插入图片描述

前言

   在学习完函数与数组部分知识后,我们常会遇见因数组越界导致死循环和函数无限递归导致栈溢出等问题。这里我们就从汇编代码入手,去理解我们所编制的代码是如何运行的,从而顺解问题。

内存地址

   首先,我们得了解一个概念,信息是需要储存的。计算机是无法直接与我们对话获取信息的,因此,科学家们构造了计算机语言。我们所编制的代码通过层层转化为二进制语言,供计算机读取。
  那信息要如何储存呢?计算机只能读懂0和1,即开与关。
  首先,计算机的CPU与内存之间是通过地址总线连接。每一根线都可以表示0或1,即每根线都能代表两种含义。对于32位的计算机,总数就有232种(4G)。
  那是不是每一根线都是一个地址呢?显然不是,通过查阅ASCII表,我们可知一共有128个字符,而每一个字符都是最基本的信息组成元素。如果我们要表示全,那必须需要8根线组成一个单元(八个二进制位)。于是,科学家就规定,一根线为一个bit,八个bit组成一个byte。最终,我们可以确定一个byte为一个地址单元,进行储存信息。
  从而进一步演化为我们所见的数据类型(char、short、int等)。
在这里插入图片描述

汇编指令

  这里涉及的汇编指令仅含下文我所讲的例子中涉及的汇编指令(完整解释各字符串含义在下文)。

xor

  xor:两个数进行逻辑异或运算,二进制位相同0,不同为1,结果赋值给第一个数。
在这里插入图片描述

mov

  mov:两个数进行赋值操作,将第二个数的值赋给第一个数。
在这里插入图片描述

lea

  lea:用于计算有效地址并将其加载到指定的寄存器中。这不是进行实际的内存引用,而是用于地址计算。
在这里插入图片描述

rep stos

  rep:重复其上面的指令。ecx的值是重复的次数。
  stos:将eax中的值拷贝到rdi指向的地址.
在这里插入图片描述

push与pop

  push:指令用于将一个寄存器或值压入栈中。栈是一种后进先出(Last In First Out)的数据结构,常用于保存函数参数、局部变量或者临时数据。
在这里插入图片描述

  pop:与push相反,将堆栈段中的一个字节弹出到某个寄存器或段寄存器或内存单元。
在这里插入图片描述

add与sub

  add:将两个数相加,并将结果存储在第一个操作数中。
在这里插入图片描述

  sub:将两个数相减,并将结果储存在第一个操作数中。
在这里插入图片描述

call与ret

  call:调用一个过程(函数),它将下一条指令的地址(也就是返回地址)压入栈中,并跳转到指定的过程地址去执行。
在这里插入图片描述
在这里插入图片描述

  ret:用于从一个过程返回。当执行RET指令时,它会从栈中弹出返回地址,并跳转到该地址继续执行。
在这里插入图片描述
在这里插入图片描述

test与 jl与jmp

  test:将两个操作数进行逻辑与运算,并根据运算结果设置相关的标志位。

  jl:若(有符号)结果小于判定值,跳转到目标地址执行指令。

  jmp:是无条件跳转指令,它告诉处理器无条件地将控制权转移给指定的地址。无论什么情况,jmp 指令后的指令都会被处理器忽略,并跳转到目标地址执行指令。
在这里插入图片描述

例题讲解(逐句讲解)

  下面以VS2022环境讲解一个简单的加法函数(不同编译器略有差异,但原理相同)

源码
#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>

int Add(int x, int y)
{
   
	return x + y;
}

int main()
{
   
	int a = 0;
	int b = 0
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值