汇编语言中的函数调用参数传递及全局与局部变量与“基址”

 更新时间:2020年02月10日 10:41:08   作者:安全客  
这篇文章主要介绍了汇编眼中的函数调用参数传递以及全局与局部变量与“基址”,本文通过图文并茂的形式给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下

GPT4.0+Midjourney绘画+国内大模型 会员永久免费使用!
如果你想靠AI翻身,你先需要一个靠谱的工具!

作为刚往底层方向走的一只菜鸟,今天为各位分享一篇名为汇编眼中的函数调用参数传递以及全局、局部变量与“基址”,好了,废话不多说,先来看看C语言代码:

本次的分享主要以画堆栈图为主,通过画图的方式来看看这段代码是如何运作的

我们先写一句汇编代码,mov eax,eax其实这句代码并没有什么用,也就是将eax的值移入eax中,这句代码对于我们的作用仅作为断点,我们F5运行下程序并且切换到反编译界面

右键之后点击Go To Disassemble,也就是进入反编译界面,我们来看看反编译的代码

这就是咱们main函数反编译后的结果,那么现在我们记录一下ebp,esp的值,并且画出现在的堆栈图

ESP = 0019FEF4

EBP = 0019FF40

黄色=ebp~esp初始的内存

那好,我们继续来看代码

这里是我们自己写的汇编代码,编译器也没有改动过可以说是本色出演,这里内存没有变化,好,那么我们接着来看add函数这里的调用

可以看到函数调用的时候首先是将3、1这两个值推入栈中,但是又有疑问了“add函数的调用是这样的add(1,3),为啥首先推入栈中的是3而不是1呢?”之所以这样是因为栈中是先进后出的,所以参数进入栈中的顺序是从右向左的,当然这里也可以看到函数中的参数是压入栈中然后取出来而不是通过通用寄存器eax,edx,ebx这些来传送参数的,其实这也好理解,因为通用寄存器只有八个,像esp,eip,ebp这样的寄存器还不能随便改,能用的也只有剩下的几个,参数超过剩下的几个咋办?那就只能用堆栈了。我们继续来看F10单步执行一下,看看堆栈的变化

我们再看看EBP和ESP

这里可以看到压入一个3后栈顶指针减去了4h,至于为啥减去4h呢?是因为一个int类型的数据宽度是4Byte=32Bit,能存入的最大数也就是0xFFFFFFFF,16进制数又是2进制数的简写形式,一个二进制数需要4Bit来存储,所以4位二进制数最大的值为1111转换为16进制后刚好为F,这样也方便了开发者,存储空间中我们看到的数据都是16进制数

可能以上讲得有些出入,如有错误,请帮忙纠正,好了,我们接着来看,接下来push 1进去,我们来看看现在的堆栈图:

继续看下面的代码:

接着是call,call指令在汇编中多用于函数调用,call指令做了两个操作,

1.Push 00401103(下一行代码地址) 2.Jmp 0040100A(函数地址)

这里我们F11一下,遇到call指令后按F11进入函数即可,这样我们就可以看到函数体中的指令

这里CALL之后看看堆栈中的变化:

继续向下走,F11后跳转到的结果如下

这里是编译器决定的,不是所有编译器call后会进入一个jmp指令中转,再F11一下

Jmp执行之后直接进入了函数体,这里将通用寄存器ebp的值存入栈中,之所以存入栈中是因为每一个函数中都要使用ebp来寻址,所以需要将ebp的原始值存入栈中,随后将esp栈顶指针的值移入ebp中,sub esp,40h是将栈顶指针加到40h这个位置,之所以是减40h是因为栈空间是从高到低的,现在我们单步执行一下看看栈中的变化

这里40h移动的位置=40h/4h=10h=16,我们看看现在堆栈的变化

Sub esp,40h这段代码我们是为函数开辟一块栈空间出来供函数存取值的,也就是我们常说的缓冲区,通常用来存储函数中的局部变量,我们接着往下看

接着向栈中推入了ebx,esi,edi,栈顶指针[esp-Ch],然后lea指令将[ebp-40h]的地址放入edi中,给ecx赋值为10h=16,也就是循环16次又将0xCCCCCCCCh赋给eax,这也被称为断点字符,然后使用rep指令将缓冲区中的值赋值为0xCCCCCCCCh,现在我们再来看看堆栈中的变化

我们看一下单步执行后的esp和ebp的结果

好勒,咱们接着往下走

这里可以看到首先是将栈中的[ebp+8]=0019FEE4+8=0019FEEC地址中的值移动到eax中,然后将eax与[ebp+Ch]=0019FEE4+Ch=0019FEF0地址中的值相加,并且将相加后的值存入eax中,栈空间无任何变化,变化的仅仅是eax,咱们单步执行看下

好了,我们接着往下看

首先将edi,esi,ebx中的值取出来,这里可以看到,我们推入和取出的顺序刚好相反,先进后出的道理,随后将ebp的值移动到esp中,这里也就改变了栈顶指针,然后pop ebp,最后ret,ret的做的操作:

pop eip(这里取出的是返回地址)

咱们单步执行一下

我们接着来看代码

这里esp+8是为了堆栈平衡,恢复最初的堆栈,我们单步一下

堆栈的变化如下:

这样就和我们没进入函数之前的堆栈一样了,程序到这里就解释了函数调用以及传参的问题。我们接着往下走

函数调用又是一个call,call的两个操作:

1、Push 0040110B(下一行代码地址)

2、Jmp 00401005(函数地址)

单步会遇到jmp,我们直接单步进入函数体

对于这里的堆栈就不画了,主要讲解一下这里的全局变量以及“基址”是啥,这里我们的全局变量z是由变量定义的时候分配指定的内存地址,在每一个函数中都可以找到,每一个全局变量都有一个唯一的内存地址,有且只有一个,在游戏外挂中经常会听到找“基址”,然而这个“基址”就是全局变量的地址,只要程序被编译那么就只有这么一个指定的地址,我们这个程序中z的地址[00424a30],打开CE

首先我们运行一下我们写好的程序

选择我们刚才运行的程序,点击加入地址,我们将00424a30这个内存地址加入进去

点击ok,我们看看它的初始值

这里完全没有自己输入值,我们改一下值,看看程序的输出

点击OK,再看一下改了之后输出的值

总结:

1、全局变量是编译后分配的一个指定内存空间,因为是公共的所以任何程序或者程序中的函数都可以调用以及修改。

2、局部变量的地址是随机的,因为每次进入函数都会随机分配一段地址给函数,这段分配的地址称为缓冲区,缓冲区也是用来存储局部变量的。

3、“基址”就是全局变量,这是外挂开发中常用到的一个词汇。

4、函数调用使用call,call指令做的两个操作:

(1)push call指令下一行地址

(2)Jmp 函数地址(编译器决定,可能先跳转到中转地址,然后跳转到函数地址)

5、汇编中的函数就是指令的集合,唯一不同的是函数最后都会用ret返回

6、函数中的参数传递是使用堆栈来传递的。

以上所述是小编给大家介绍的汇编语言中的函数调用参数传递及全局与局部变量与“基址”,希望对大家有所帮助!

蓄力AI

微信公众号搜索 “ 脚本之家 ” ,选择关注

程序猿的那些事、送书等活动等着你

原文链接:https://www.anquanke.com/post/id/198215

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 reterry123@163.com 进行投诉反馈,一经查实,立即处理!

相关文章

  • 汇编语言之寄存器详解

    汇编语言之寄存器详解

    这篇文章主要介绍了汇编语言之寄存器详解,需要的朋友可以参考下
    2020-01-01
  • 汇编语言乘指令 MUL、IMUL的具体使用

    汇编语言乘指令 MUL、IMUL的具体使用

    这篇文章主要介绍了汇编语言乘指令 MUL、IMUL的具体使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • os_object_release Crash 排查记录分析

    os_object_release Crash 排查记录分析

    这篇文章主要为大家介绍了os_object_release Crash 排查记录分析,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • 汇编语言中mov和lea指令的区别详解

    汇编语言中mov和lea指令的区别详解

    指令(instruction)是一种语句,它在程序汇编编译时变得可执行。本文给大家总结一下汇编语言中mov和lea指令的区别详解,感兴趣的朋友跟随小编一起看看吧
    2020-01-01
  • ARM汇编解决阶乘及大小写转换的问题

    ARM汇编解决阶乘及大小写转换的问题

    这篇文章主要介绍了ARM汇编解决阶乘及大小写转换,包括ARM汇编大小写转换以及存入内存的相关知识,本文给大家介绍的非常详细,需要的朋友可以参考下
    2021-11-11
  • 汇编语言中debug命令使用小结

    汇编语言中debug命令使用小结

    Debug是DOS、Windows都提供的实模式(8086方式)程序的调试工具,本文主要介绍了汇编语言中debug命令使用小结,具有一定的参考价值,感兴趣的可以了解一下
    2024-03-03
  • 汇编语言基础理解计算机底层技术原理

    汇编语言基础理解计算机底层技术原理

    这篇文章主要为大家介绍了汇编语言基础,理解计算机底层原理,想要成为高级程序员,我们必须要学会汇编语言,汇编语言是非常重要的计算机底层技术,一般用于底层的编写
    2021-11-11
  • 计算机系统汇编语言和机器语言深入理解

    计算机系统汇编语言和机器语言深入理解

    这篇文章主要为大家介绍了计算机系统汇编语言和机器语言深入理解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • 汇编语言Debug命令详解教程

    汇编语言Debug命令详解教程

    这篇文章主要为大家介绍了汇编语言Debug命令的教程,文中对Debug的命令进行了全面的讲解有需要的朋友可以借鉴参考共同学习下,希望能够有所帮助
    2021-11-11
  • 汇编语言80x86系统通用数据传送指令详解

    汇编语言80x86系统通用数据传送指令详解

    这篇文章主要为大家介绍了汇编语言80x86系统通用的数据传送指令详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2021-11-11

最新评论