首页
学习
活动
专区
圈层
工具
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

为什么ebx保存在一个简单函数的堆栈框架中,调用gets?

ebx保存在一个简单函数的堆栈框架中,调用gets是因为在函数调用过程中,ebx寄存器被用作基址寄存器,用于访问函数的局部变量和参数。而调用gets函数是为了从标准输入流中读取用户输入的字符串。

在堆栈框架中,函数的局部变量和参数被分配在栈上,而ebx作为基址寄存器可以方便地访问这些局部变量和参数。通过保存ebx的值,函数可以在执行过程中正确地访问和操作这些数据。

调用gets函数是为了从标准输入流中读取用户输入的字符串。gets函数会将用户输入的字符串存储到指定的内存地址中,而ebx寄存器保存了这个内存地址,因此可以将用户输入的字符串保存到函数的局部变量或参数中。

然而,需要注意的是,使用gets函数存在安全风险。gets函数没有对输入的字符串长度进行限制,可能导致缓冲区溢出漏洞,使得恶意用户可以输入超出预期长度的字符串,从而覆盖其他内存区域的数据。为了避免这种安全问题,推荐使用更安全的输入函数,如fgets函数,并且在使用任何输入函数时都应该对输入的长度进行合理的限制和验证。

腾讯云相关产品和产品介绍链接地址:

相关搜索:为什么我的.net析构函数不是在这个非常简单的场景中调用的?为什么此代码不能调用python中另一个函数内的函数为什么从mocked类中的另一个函数调用的函数测试失败?另一个文件中的函数调用在Django rest框架中不起作用Mapbox:为什么我的for循环不在flyTo函数的位置列表中调用?"...addEventListener不是一个函数“为什么一个异步函数中的多个setState调用会导致多个呈现?构造函数中的虚拟成员调用 - 为什么一个好,另一个不行?在python DEAP包中,为什么一个函数可以从没有这个函数的模块中调用?为什么在单独的行上调用一个函数会改变c++中的结果?我如何在由于moto的mock而不一定存在的另一个函数中模拟对象的函数调用为什么在同一个智能合约中调用相同的函数时,Txn使用的Gas不同?为什么多次调用一个动画函数会导致它跳过三个js中的动画?我不明白为什么dplyr中的填充函数在调用包含对象的数据集时显示该对象不存在当'x/ylab()‘函数已经存在时,为什么在ggplot中的'scale_x/y_continuous()’函数中有一个'name‘参数呢?为什么从另一个调用的函数不会显示在节点应用程序的配置文件输出中?我想要跟踪一个Java函数被调用的次数,并将其保存在数据库中。做到这一点的最好方法是什么?我正在尝试在Typescript中创建一个简单的计时器,在浏览器控制台中它显示"this.pad不是一个函数“,我不明白为什么我需要创建一个发送电子邮件的函数,为什么当我在main中调用它以确认它是否已发送时,它显示为null?
相关搜索:
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

ROP的基本原理和实战教学,看这一篇就够了!

ecx ; pop ebx ; ret 简单展示部分内容,与上一个选取原理是一样的,为了方便,我们选择最后一行。...图片 当然也可以进行堆栈平衡,在执行完gets()函数后提升堆栈(add esp, 4),堆栈位置如下: 程序在读写数据的时候是通过地址查找的,如果函数调用之前的堆栈与函数调用之后的堆栈不一致,就可能导致找不到数据或找到的数据错误...图片 这样构造使得我们的堆栈逻辑更好看,一个函数一个函数的顺序执行,从压入形参到结束,显得有条理,但是只要达到目的即可,第一种或许更方便一些。...此处的溢出用来获取put函数的真实地址,怎么再去进行执行system('bin/sh')呢?如果存在两个溢出点就完美了,可惜只有一个。...怎么构造之前简单了解用户代码的入口和系统代码的入口,在一个程序运行中有两个入口,一个是main(),另一个是_start(),简单来说,main()函数是用户代码的入口,是对用户而言的;而_start(

3.3K30

《深入理解计算机系统》(CSAPP)实验三 —— Buf Lab

在此代码中,定义了一个32个字节空间的buf来存储字符。   Gets()从输入流中获取一个字符串,并将其存储到其目标地址(buf)。但是,Gets()无法确定buf是否足够大以存储整个输入。...当Gets遇到此字节时,它将终止字符串。 栈帧结构 ? 首先简单理解下函数调用过程中的栈帧结构。如上图所示,为函数P调用函数Q时,程序的栈帧结构。 当前正在执行的过程的帧总是在栈顶。...Level 1: Sparkler   Level1 和Level0差不多,唯一的区别是 fizz(int) 函数有一个整型的参数,并且在 fizz函数中还要校验cookie, test函数调用getbuf...当调用函数(在本例中为getbuf)执行其ret指令时,程序将开始在堆栈上执行指令,而不是返回。通过这种攻击方式,您可以获得该程序几乎可以执行任何操作。您放在堆栈上的代码称为漏洞利用代码。...在GDB调试中,堆栈位置也会有差异,因为GDB将堆栈空间用于其自身的某些状态。   在调用getbuf的代码中,使用了某些手段(稳定因素),从而使两次运行之间,getbuf的堆栈框架将保持一致。

2.2K20
  • Win32汇编:过程与宏调用

    接着来简单介绍下关于堆栈操作的两个寄存器,CPU系统提供了两个特殊的寄存器用于标识位于系统栈顶端的栈帧....◆堆栈参数传递◆ 在通常情况下ESP是可变的,随着栈的生产而逐渐变小,而EBP寄存器是固定的,只有当函数的调用后,发生入栈操作而改变. 1.在32位系统中,执行PUSH压栈时,堆栈指针自动减4,再将压栈的值复制到堆栈指针所指向的内存地址.... 2.在32位系统中,执行POP出栈时,从栈顶移走一个值并将其复制给内存或寄存器,然后再将堆栈指针自动加4. 3.在32位系统中,执行CALL调用时,CPU会用堆栈保存当前被调用过程的返回地址,直到遇到...Sum的过程,实现EBX+ECX并将结果保存在EAX寄存器中. .data TheSum DWORD ?...一个简单的宏: MyCode macro xor eax,eax xor ebx,ebx xor ecx,ecx xor edx,edx endm .code main PROC MyCode

    66120

    Win32汇编:过程与宏调用

    ,而ESP寄存器的值通常是指向特定位置的一个32位偏移值,我们很少需要直接操作ESP寄存器,相反的ESP寄存器总是由CALL,RET,PUSH,POP等这类指令间接性的修改.接着来简单介绍下关于堆栈操作的两个寄存器...◆堆栈参数传递◆在通常情况下ESP是可变的,随着栈的生产而逐渐变小,而EBP寄存器是固定的,只有当函数的调用后,发生入栈操作而改变.1.在32位系统中,执行PUSH压栈时,堆栈指针自动减4,再将压栈的值复制到堆栈指针所指向的内存地址....2.在32位系统中,执行POP出栈时,从栈顶移走一个值并将其复制给内存或寄存器,然后再将堆栈指针自动加4.3.在32位系统中,执行CALL调用时,CPU会用堆栈保存当前被调用过程的返回地址,直到遇到RET...Sum的过程,实现EBX+ECX并将结果保存在EAX寄存器中..dataTheSum DWORD ?....,一旦定义后,宏过程就可以在程序中被调用任意多次,调用宏过程的时候,宏内的语句块将替换到调用的位置,宏的本质是替换,但像极了子过程,宏可定义在源程序的任意位置,但一般放在.data前面.一个简单的宏:MyCode

    46830

    深入理解计算机系统:内存越界引用和缓冲区溢出

    程序运行时,其内存里面一般都包含这些部分: (1)程序参数和程序环境; (2)程序堆栈(堆栈则比较特殊,主要是在调用函数时来保存现场,以便函数返回之后能继续运行),它通常在程序执行时增长,一般情况下...在栈中分配某个字节数组来保存一个字符串,但是字符串的长度超出了为数组分配的空间。C对于数组引用不进行任何边界检查,而且局部变量和状态信息,都存在栈中。...void echo() { char buf[8] ; gets(buf) ; puts(buf) ; } 输入的字符数量   被破坏的状态 0—7        无 8—11      ...保存的%ebx的值 12—15      保存的%ebp的值 16—19      返回地址 20+         caller中保存的状态 执行攻击代码exploit code 用一个指向攻击代码的指针覆盖返回地址达到跳转到攻击代码的效果...方式一:攻击代码会使用系统调用启动一个shell程序,给供给者提供一组操作系统函数; 方式二:执行一些未授权的任务,修复对栈的破坏,然后第二次执行ret指令,表面上正常返回到调用者; 蠕虫和病毒的区别

    53520

    Delphi异常机制与SEH

    当MOV [EBX], 0发生内存访问错后,系统挂起,查找SEH处理链表,通知ExceptionHandler进行处理,ExceptionHandler中,将EBX修复到一个可以访问的内存位置,再通知系统恢复环境继续执行...1 、 VCL 的顶层异常捕获 在DELPHI开发的程序中,出错的时候,我们很少看到出现一个错误对话框,提示点确定结束程序,点取消调试。而在VC或VB里就很常见,这是为什么呢?...VCL里比较特殊的SEH应用吧,过程大概就是,对构造函数进行保护,如果出现异常就调用析构函数释放。...,这个时候VCL又会主动调用析构函数,结果b.free的时候就出错了。...所以在析构函数里释放对象的时候,一定要注意判断对象是否存在。

    1.2K10

    缓冲区溢出攻击初学者手册(更新版)

    其中EIP指向的地址总是包含下一个执行代码。 数据段,变量空间和动态缓冲器。 堆栈段,这是用来给函数传递变量的和为函数变量提供空间。栈的底部位于每一页的虚拟内存的末端,同时向下运动。...2 函数 函数是一段代码段的代码,它被调用,执行一个任务,之后返回执行的前一个线程。或是把参数传递给函数,通常在汇编语言中,看起来是这样的(这是一个很简单的例子,只是为了了解一下概念)。...主函数调用了function(0); 变量是0,主要把它压入栈中,同时调用该函数。函数使用popl来获取栈中的变量。完成后,返回0×8054327。...如果代码中存在溢出的地方,这个返回值会被覆盖,并且指针指向内存中的下一个位置。...如果有溢出存在,函数的返回值地址是可以变的,从而改变程序的执行线程。 4 Shellcode 为了简单,Shellcode使用简单的汇编指令,我们写在栈上,然后更改返回地址,使它返回到栈内。

    1.4K90

    CC++ 编写并提取通用 ShellCode

    简易 ShellCode 虽然可以正常被执行,但是还存在很多的问题,因为上次所编写的 ShellCode 采用了硬编址的方式来调用相应API函数的,那么就会存在一个很大的缺陷,如果操作系统的版本不统一就会存在调用函数失败甚至是软件卡死的现象...为什么要查找 Kernel32.dll 的地址而不是 User32.dll,这是因为我们最终的目的是调用 MessageBox 这个函数,而该函数位于 User32.dll 这个动态链接库里,默认情况下是无法直接调用的....dll 这个动态链接库的基地址,而Dll文件本质上也是PE文件,在Dll文件中存在一个导出表,其内部记录着该Dll的导出函数。...函数的 RVA 地址和名字按照顺序存放在上述两个列表中,我们可以在列表定位任意函数的RVA地址,通过与动态链接库的基地址相加得到其真实的VA,而计算的地址就是我们最终在 ShellCode 中调用时需要的地址...LoadLibraryA的地址 lea edi,[esi-0xc] // 后面会利用edi的值来调用不同的函数 // ===开辟内存空间,这里是堆栈空间 xor ebx,ebx

    52120

    汇编角度看函数堆栈调用

    下面以主函数调用求和函数分析函数堆栈调用 带着以下一个问题来探索: (1)形参的内存空间的开辟和清理是由调用方还是由被调用方执行的? (2)主函数调用函数结束后,主函数从哪里开始执行?...[pop 寄存器] 功能:出栈,以一个寄存器接受出栈的数据。包含两个动作:将栈中的数据保存在寄存器中,同时栈顶指针向下(高地址)偏移。...这就是为什么当我们访问未初始化内存中的内容,看到的是如下图的情况。...2.0040104E mov esp,ebp使得被调用函数栈帧回退。此时栈帧空间的内容还存在。 3.pop ebp 两个动作,出栈,并将出栈的值赋给ebp。...所以形参内存是由调用方清理的。 2.将eax寄存器中的值`30`放入[ebp-0Ch]指向的四字节内存块中。 到这里,函数堆栈调用的过程就完全展示出来了。

    67520

    恶意样本对抗栈回溯检测机制的套路浅析

    在本文中我将会简单分析和推测一下这类恶意样本都是通过哪些套路来实现和栈回溯机制的对抗。需要注意的是,文中讨论的堆栈都是代指线程在用户层的堆栈,并未涉及内核层的堆栈。...命中断点之后,发现无法通过 kv 指令栈回溯来获取该线程当前时刻的调用栈序列,能获取到的栈帧只有当前所处的函数调用。而继续跟进该函数里所调用的任何一个函数中,发现调用栈仍旧只有一个栈帧。...EBP 始终保持不变 mov esp, ebp ; 将 EBP 的值赋给 ESP 寄存器,执行后 ESP 指向地址存储属于调用函数的 EBP 的值 pop ebp ; 弹出保存在栈中的调用函数的...EBP 的并赋给 EBP 寄存器 ret ; 弹出保存在栈中的调用函数中调用位置的下一条指令的地址给 EIP 寄存器 根据以上的函数调用逻辑容易知道,在函数体代码的任何位置,EBP...要是样本的 ShellCode 更进一步,窃取其他线程的堆栈部分数据覆盖到自己构造的堆栈的高内存部分,那么在调试器或检测系统在栈回溯时,遍历到上层的调用项,被诱导进入另一个线程的调用栈序列中,那么获取到的数据就可能已经不是当前线程的数据了

    86520

    5.5 汇编语言:函数调用约定

    函数是任何一门高级语言中必须要存在的,使用函数式编程可以让程序可读性更高,充分发挥了模块化设计思想的精髓,今天我将带大家一起来探索函数的实现机理,探索编译器到底是如何对函数这个关键字进行实现的,并使用汇编语言模拟实现函数编程中的参数传递调用规范等...不同的两次函数调用,所形成的栈帧也不相同,当由一个函数进入另一个函数时,就会针对调用的函数开辟出其所需的栈空间,形成此函数的独有栈帧,而当调用结束时,则清除掉它所使用的栈空间,关闭栈帧,该过程通俗的讲叫做栈平衡...这种调用方式规定函数调用者在将参数压入栈中后,再将控制权转移到被调用函数,被调用函数通过栈顶指针ESP来访问这些参数。函数返回时,由调用者程序负责将堆栈平衡清除。...CDECL调用约定的特点是简单易用,但相比于其他调用约定,由于栈平衡的操作需要在函数返回后再进行,因此在一些情况下可能会带来一些性能上的开销。...它通常采用被调用者平衡堆栈的方式,类似于STDCALL调用约定。但是,FASTCALL约定规定函数的前两个参数在ECX和EDX寄存器中传递,节省了压入堆栈所需的指令。

    33620

    5.5 汇编语言:函数调用约定

    函数是任何一门高级语言中必须要存在的,使用函数式编程可以让程序可读性更高,充分发挥了模块化设计思想的精髓,今天我将带大家一起来探索函数的实现机理,探索编译器到底是如何对函数这个关键字进行实现的,并使用汇编语言模拟实现函数编程中的参数传递调用规范等...不同的两次函数调用,所形成的栈帧也不相同,当由一个函数进入另一个函数时,就会针对调用的函数开辟出其所需的栈空间,形成此函数的独有栈帧,而当调用结束时,则清除掉它所使用的栈空间,关闭栈帧,该过程通俗的讲叫做栈平衡...这种调用方式规定函数调用者在将参数压入栈中后,再将控制权转移到被调用函数,被调用函数通过栈顶指针ESP来访问这些参数。函数返回时,由调用者程序负责将堆栈平衡清除。...CDECL调用约定的特点是简单易用,但相比于其他调用约定,由于栈平衡的操作需要在函数返回后再进行,因此在一些情况下可能会带来一些性能上的开销。...它通常采用被调用者平衡堆栈的方式,类似于STDCALL调用约定。但是,FASTCALL约定规定函数的前两个参数在ECX和EDX寄存器中传递,节省了压入堆栈所需的指令。

    27620

    系统调用(int 0x80)详解

    大家好,又见面了,我是你们的朋友全栈君 1、系统调用初始化 在系统启动时,会在sched_init(void)函数中调用set_system_gate(0x80,&system_call),设置中断向量号...为什么不能保存到用户态堆栈,如果保存了用户态堆栈,那么,这些栈内存区域,用户程序就可以必改定,那么,程序就很容易被攻击了,直接修改CS:EIP对应的栈内存,那么,你懂的^_^。...现场信息是保存在当前进程的内核态堆栈中,由于已经进入了内核态,在_system_call函数中执行push操作,此时被push的数据是存储也就在内核栈中。...//系统调用函数的返回值入栈 关于进程状态的变化,参考书上的说明,这部分,理解的还不够,后续再分析???...当在中断处理函数(陷阱门)中执行时,是可被中断(中断门)的,因为eflags标志中的TF被设置为允许中断的。因而有可能在时钟中断函数(do_timer)中,本进程的时间片可能被修改为0。

    1.6K40

    函数栈帧的创建与销毁

    前言 最近在学习C语言的过程中遇到了一些问题,在询问老师和查询相关资料的基础上了解到了函数栈帧的相关概念,对下列问题也有了答案。 局部变量是如何创建的? 未初始化的局部变量为什么是随机值?...(如果给一个变量未初始化,打印该变量中的内容就会出现一些没有实际意义的文字或字母) 函数是如何调用的?(过程是什么样的?) 函数在调用过程中是如何传参的? 形参和实参有什么联系和区别?...栈帧中维持着函数调用所需要的各种信息,包括函数的入参、函数的局部变量、函数执行完成后下一步要执行的指令地址、寄存器信息等。...EBP是"基址指针"(BASE POINTER), 它最经常被用作高级语言函数调用的"框架指针"(frame pointer)。...二、函数栈帧介绍 每个函数被调用时都会建立栈帧,在接下来的调试过程中我将会进一步解释。

    53520

    5.10 汇编语言:汇编过程与结构

    例如,要将从堆栈中弹出的值存储到BX寄存器中,可以使用以下指令: POP EBX 从汇编代码的角度来看,POP指令将从堆栈中取出一个值,并将其存储到目的操作数中,它是一个出栈操作。...在函数调用时,PUSH指令被用于向堆栈中推送函数的参数,这些参数可以是寄存器、立即数或者内存中的某个值。在函数返回之前,POP指令被用于将堆栈顶部的值弹出,并将其存储到寄存器或者内存中。...因此,被调用函数必须知道其在堆栈上分配的内存大小,并将该大小与其ret指令中的参数相匹配,以便调用函数可以正确恢复堆栈指针位置。 当平栈由调用者完成时,调用函数需要在调用子函数之前平衡堆栈。...因此,调用函数需要知道子函数在堆栈上分配的内存大小,并在调用子函数之前向堆栈提交额外的空间。调用函数可以使用add esp, N指令来恢复堆栈指针的位置,其中 N 是被调用函数在堆栈上分配的内存大小。...该指令会将新的基准指针ebp 压入堆栈同时将当前的基准指针ebp存储到另一个寄存器ebx中,然后将堆栈指针esp减去指定大小的值,获取新的基地址,并将新的基地址存储到ebp 中。

    22620

    5.10 汇编语言:汇编过程与结构

    例如,要将从堆栈中弹出的值存储到BX寄存器中,可以使用以下指令:POP EBX从汇编代码的角度来看,POP指令将从堆栈中取出一个值,并将其存储到目的操作数中,它是一个出栈操作。...在函数调用时,PUSH指令被用于向堆栈中推送函数的参数,这些参数可以是寄存器、立即数或者内存中的某个值。在函数返回之前,POP指令被用于将堆栈顶部的值弹出,并将其存储到寄存器或者内存中。...因此,被调用函数必须知道其在堆栈上分配的内存大小,并将该大小与其ret指令中的参数相匹配,以便调用函数可以正确恢复堆栈指针位置。当平栈由调用者完成时,调用函数需要在调用子函数之前平衡堆栈。...因此,调用函数需要知道子函数在堆栈上分配的内存大小,并在调用子函数之前向堆栈提交额外的空间。调用函数可以使用add esp, N指令来恢复堆栈指针的位置,其中 N 是被调用函数在堆栈上分配的内存大小。...该指令会将新的基准指针ebp 压入堆栈同时将当前的基准指针ebp存储到另一个寄存器ebx中,然后将堆栈指针esp减去指定大小的值,获取新的基地址,并将新的基地址存储到ebp 中。

    47320

    大神洗礼第四讲——函数相关及编程技巧

    2、 Call Convention(函数调用约定) 、_cdecl a、 参数从右向左压入堆栈 b、 函数被调用者修改堆栈 c、 在win32应用程序里,宏APIENTRY,WINAPI,...每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小会比调用_stdcall函数的大。...、_stdcall a、 压栈方式与_cdecl一样,与之不一样的是堆栈的平衡不是由函数调用者完成,而是自身完成,在退出时自己清空堆栈。...3、 跟踪汇编代码看函数参数的调用机制 我们看这样一个简单的函数, 编译器翻译的汇编指令如下: 、void Test1(){}  1 void Test1() 2 { 3 013516E0...} 29 在main函数调用的结果printf("%d\n", MyFunc()); 2012110222341843.png 练习: 、无参数的情况(不在堆栈上展开) 1 void

    664100

    1.4 编写简易ShellCode弹窗

    由于如上机制的存在,导致user32.dll模块地址不确定,也就会导致其地址内部的API函数地址也会发生一定的变化,下图仅作为参考图; 在获取到MessageBoxA函数的内存地址以后,我们接着需要获取一个...返回值传递:函数返回时将返回值存储在EAX寄存器中。 栈的使用:函数被调用前,调用者将参数压入栈中;被调用者在返回前清理栈,以确保栈的平衡。...函数调用:在调用函数之前,调用者将返回地址(Return Address)和EBP寄存器的值保存在栈中,并将ESP寄存器指向参数列表的最后一个元素;在函数返回之后,调用者通过将之前保存的EBP和返回地址弹出栈中...总之,stdcall调用约定将参数按照从右到左的顺序压入栈中,由被调用者清理栈,返回值存储在EAX寄存器中,函数调用者和被调用者都需要遵循一定的栈使用规则。...在实际的编程中,一般还是先将地址赋值给eax寄存器,然后再CALL调用相应的寄存器实现调用,比如现在笔者有一个lyshark(a,b,c,d)函数,如果我们想要调用它,那么它的汇编代码就应该编写为: push

    32110

    封包式游戏功能的原理与实现

    封包式功能的实现步骤 1、定位到游戏的发包函数 2、通过发包函数定位到明文发包函数 3、通过明文发包函数定位到封包加密函数 4、复制整个封包加密函数到自己的dll 5、组包调用游戏功能 整个过程看似简单...不过,发包函数在下断点的时候,可能会碰到下面两个棘手的问题: 1、明明对 send() 函数下断了,缺断不下来 2、由于游戏中存在一个发包线程,所以即使断下 send() 函数,也无法回溯出有用的逻辑...2、搜索 send 函数的特征,定位到重写的 send 函数 线程发包 接下来解决第二个问题,游戏单独起了一个线程进行发包 线程发包的形态和特点 1、发包函数断的很频繁 2、任何功能在发包函数断下,调用堆栈都是一样的...判断的方法是对比 WSASend 和找到地址的调用堆栈。 我们发现两个调用堆栈的地址是相同的,说明还没有跳出发包线程。需要继续追 eax 的来源然后下写入断点。 ?...在加密的封包内容处下断点,喊话让游戏断下,并且在堆栈中找到第一个返回地址 ? 分析这个 call 的相关参数, esi 是一个结构体指针 ? +0 的位置指向的是一个虚函数表 ?

    3.8K30

    C语言 | C++ 堆栈工作机制

    我们知道,局部变量是存储在堆栈中的;debug 时,查看堆栈可以知道函数的调用顺序;函数调用时传递参数,事实上是把参数压入堆栈,听起来,堆栈象一个大杂烩。...这时 main 以及之前的函数对应的堆栈帧已经存在在堆栈中了,如下图所示: 图1 参数入栈  当 foo 函数被调用,首先,caller(此时caller为main函数)把 foo 函数的两个参数:a...个字节)如下图所示: 图6 我还不知道编译器为什么这么设计,或许是为了在堆栈中插入调试数据,不过这无碍我们今天的讨论。...在 foo 函数中用到的通用寄存器是 EBX,ESI,EDI,将它们压入堆栈,如图所示: 图7 至此,一个完整的堆栈帧建立起来了。...事实上,调试器正是这么做的,这也就是为什么调试时我们查看函数调用顺序时总是说“查看堆栈”了。

    7.8K88
    领券