`
leonard1853
  • 浏览: 85282 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

子程序的压栈方式

阅读更多

当指定子程序的语言模式,或者使用.model中指定的语言模式时,如stdcall、pascal等,子程序的参数压栈方式是不同的,例如stdcall模式下,参数是从右向左压栈,而在pascal模式下,参数是从左向右压栈。

 

下面,以stdcall模式为例,说明调用一个子程序时,是如何压栈的,假设压栈前,esp的值为addr:

 

addr ……
addr - 4 ebp + 16 参数三
addr - 8 ebp + 12 参数二
addr - 12 ebp + 8 参数一
addr - 16 ebp + 4 返回地址
addr - 20 ebp 保存原ebp值,并且mov ebp, esp
addr - 24 ebp - 4 局部变量1
addr - 28 ebp - 8 局部变量2
……

 

如上表所示,如果栈是向下生长的,则在将参数和返回地址进栈后,需要保存当前的ebp,并且将当前的esp值赋予ebp,从而可以用ebp访问参数或者局部变量。同时,编译器在编译时,会在ret前,加上leave这条指令, 实现mov esp,ebp, pop ebp的功能。

 

而在子程序中如果要用uses或是pushad/popad对实现环境变量保存时,如果返回结果是保存在eax中,则一定要记得将返回结果保存起来,否则eax中的值会被重置为调用前的值,如下列代码所示:

 

.386  
.model flat, stdcall  
  
include    windows.inc  
include    kernel32.inc  
includelib kernel32.lib 
include	   user32.inc
includelib user32.lib

include    masm32.inc 
includelib masm32.lib  
include    debug.inc 
includelib debug.lib  
  
.data  
ddResult  dd  ?  
  
.code  
calc proc one, two, three  
    pushad  
    
    mov eax, one  
    add eax, two  
    add eax, three  
  
    mov ddResult, eax ;如果不在这里保存,返回的eax会是原来的值  
      
    PrintDec eax  
    PrintLine
    
    popad  
    
    PrintDec eax  
    PrintLine
    ret  
calc endp  
  
start proc  
    invoke calc, 1, 2, 3  
    PrintDec ddResult  ; 6 
     
    PrintLine
    PrintDec eax  ;
      
    ret  
start endp  
  
end start

 输出结果:


分享到:
评论

相关推荐

    易语言汇编子程序跳转源码

    汇编子程序,也称为函数或过程,在易语言中,它允许程序员以模块化的方式编写代码,提高代码的可读性和复用性。这些子程序通常包含一系列特定的指令,用于执行特定的任务。汇编语言是与机器硬件紧密相关的编程语言,...

    子程序设计实验报告

    2. **近程调用与远程调用的区别**:了解两种不同类型的子程序调用方式及其适用场景。 3. **通过堆栈传递参数的方法**:掌握利用堆栈结构在调用子程序时传递参数的技术。 4. **多模块程序设计方法**:学习如何组织多...

    c语言调用汇编子程序

    关于参数传递,当调用汇编子程序时,C语言会按照约定将前几个参数压栈,并将栈顶地址传递给FP。在实验中,R0-R2保存了a, b, c,而e和d分别通过FP-4和FP-8获取。在处理整数数组e[3]和f[3]时,C语言将两个数组的首地址...

    汇编 子程序设计 求N!

    - 子程序`FACT`通过递归方式计算阶乘,当N等于0时返回1,否则将(N-1)!的结果与N相乘,然后返回。 **实验步骤与源代码** 实验中定义了以下几个关键部分: - **堆栈段(STACKSG)**:用于存储临时数据和返回地址。...

    汇编语言实验七子程序设计2.doc

    在本实验中,主题是关于使用IBM-PC汇编语言进行子程序设计。实验的目标主要集中在三个方面: 1. 掌握主程序与子程序之间的调用关系及调用方法:在汇编语言编程中,主程序(main program)通常负责整体流程的控制,...

    易语言使用汇编调用子程序

    在易语言中,有时我们需要使用汇编语言来实现一些底层或者高效的代码,这就涉及到了“易语言使用汇编调用子程序”的技术。本文将深入探讨这个主题,包括如何在易语言中调用汇编子程序,以及相关的实践应用。 一、...

    汇编语言程序设计子程序

    实现对算法的设计,并使用汇编语言对于编制子程序的说明文件包括:子程序名,即子程序入口地址,子程序功能,入口条件,出口条件,和受影响的寄存器,此外主程序和子程序之间的参数传递,有寄存器传参,存储单元传参...

    mcs51汇编子程序.

    1. **调用子程序**:使用`CALL`指令,后跟子程序的地址,将程序计数器(PC)压栈,然后跳转到子程序地址。 2. **返回**:子程序执行完后,使用`RET`指令将栈顶的地址弹出并加载到PC,恢复程序执行流。 **三、8051...

    8086 汇编语言子程序程序设计.pdf

    在子程序的入口处,通常要将需要使用的寄存器的值压栈(`PUSH`),以便在子程序返回前,能够恢复它们的原始值。在子程序的末尾,使用`RET`指令返回主程序。 在实验一中,涉及了如何使用子程序来计算数组元素的和。...

    51单片机C语言调用汇编子程序的简便方法_单片机_51单片机C语言调用汇编子程序的简便方法_.zip

    1. 定义汇编子程序:在汇编文件中编写子程序,通常以`.asm`或`.s`为扩展名。在这个子程序中,我们可以直接操作硬件寄存器,执行特定的低级任务。 2. 创建函数原型:在C语言代码中,为汇编子程序创建一个函数声明。...

    汇编-子程序设计-阶乘.doc

    - **堆栈**:常用方式是通过堆栈传递参数或参数地址,调用者将参数压栈,子程序在被调用时弹栈获取。 - **多模块间参数传递**:在多个模块间传递参数,可能需要更复杂的机制,如全局数据区或内存映射。 5. **增强...

    第五次汇编语言实验报告-子程序设计.docx

    3. 学习通过寄存器、内存单元和堆栈这三种方式传递子程序参数。 4. 增强模块化编程思想,将复杂程序划分为小的独立功能。 5. 理解子程序的嵌套调用和递归调用。 实验环境: 操作系统:Windows 8 编译器:MASM 实验...

    MCS-51单片机实用子程序库

    MCS-51单片机实用子程序库是针对51系列单片机设计的一组汇编语言编写的子程序,这些子程序涵盖了定点运算和浮点运算等多个方面,为51单片机的开发提供了便利。以下是这些子程序的主要功能和应用: 1. **定点运算子...

    MCS51单片机实用子程序.pdf

    文章还提到了子程序的使用方式,分为两种: 1. **全链接方式**:简单便捷,但可能增加程序长度,包含不必要的代码。 2. **选择性链接方式**:根据需要选择子程序,使程序更紧凑,但需仔细删选。 通过以上介绍,可以...

    子程序、中断1

    寄存器传参直接将参数放入特定的寄存器,而栈传参则是通过将参数压栈,然后在子程序内部进行读取。返回值通常存储在`ax`寄存器中。为了保持栈的平衡,调用者和被调用者都需要进行相应的栈操作,如在调用前保存状态,...

    汇编-第12课 子程序续.pdf

    栈传递参数时,通常先将参数压栈,然后调用子程序,子程序内部会保存栈顶指针`SP`到`BP`,并可能保存其他寄存器内容,以备后续使用。在子程序返回前,需要恢复这些寄存器的值,并进行堆栈平衡,即弹出参数。 堆栈...

    汇编让易语言子程序返回通用型

    1. 定义入口:在汇编子程序的开头,你需要指定子程序的入口点,这通常是`PROC`指令。例如: ```assembly PROC MyAssemblyProc ``` 2. 处理参数:易语言中的参数传递通常是通过栈来完成的。你需要了解易语言的...

    IBM-PC汇编语言程序设计(6)

    参数也可以通过堆栈传递,例如,主程序将参数值压栈,然后调用子程序,子程序从堆栈中获取参数。这种方式在处理多参数时较为常见。 **6.3 子程序嵌套与递归** 子程序可以嵌套,即一个子程序内部调用另一个子程序。...

    汇编-第11课 子程序.pdf

    本课主要讲解了汇编语言中的子程序概念及其调用机制,以及中断和一些处理器控制类指令的使用。 子程序在汇编语言中类似于高级语言中的函数,它们封装了一段可重复使用的代码,可以被其他部分的程序调用。对于段内...

    易语言汇编实现子程序回调应用源码-易语言

    因此,开发者需要了解易语言的内部调用规范,如参数传递方式、堆栈管理规则等,才能正确地实现汇编子程序的回调。 回调的实现还涉及到函数指针的概念。在易语言中,可以使用“函数地址”数据类型来存储子程序的地址...

Global site tag (gtag.js) - Google Analytics