CPU指令解析及函数调用机制

本文涉及的产品
云解析 DNS,旗舰版 1个月
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: CPU指令解析及函数调用机制

一、CPU指令解析


最常用的mov指令


       指令中最常使用的是对寄存器和内存进行数据存储的 mov 指定数据的存储地和读出源。操作数中可以指定寄存器、常数、标签(附加在地址前),以及用方括号([ ])围起来的这些内容。如果指定了没有用([ ])方括号围起来的内容,就表示对该值进行处理;如果指定了用方括号围起来的内容,方括号的值则会被解释为内存地址,然后就会对该内存地址对应的值进行读写操作。让我们对上面的代码片段进行说明指令,mov指令的两个操作数,分别用来


mov
ebp,espeax,dword ptr [ebp+8]


  mov ebp,esp中,esp 寄存器中的值被直接存储在了ebp中,也就是说,如果esp 寄存器的值是100的话那么 ebp 寄存器的值也是100.


       而在 mov eax,dword ptr [ebp+8]这条指令中,ebp寄存器的值+8后会被解析称为内存地址。如果 ebp


       寄存器的值是100的话,那么eax寄存器的值就是100+8的地址的值。dword ptr 也叫做double word pointer 简单解释一下就是从指定的内存地址中读出4字节的数据


对栈进行push和pop


       程序运行时,会在内存上申请分配一个称为栈的数据空间。栈(stack)的特性是后入先出,数据在存储时是从内存的下层(大的地址编号)逐渐往上层(小的地址编号)累积,读出时则是按照从上往下进行读取的。


栈的模型:



   栈的存储临时数据的区域,它的特点是通过 push 指令和pop指令进行数据的存储和读出。向栈中存储数据称为 入栈 ,从栈中读出数据称为 出栈 ,32位 x86 系列的CPU中,进行1次push或者pop,即可处理32位(4字节)的数据


二、函数的调用机制


       下面我们一起来分析一下函数的调用机制,我们以上面的C语言编写的代码为例。首先,让我们从MyFunc 函数调用 AddNum 函数的汇编语言部分开始,来对函数的调用机制进行说明。栈在函数的调用中发挥了巨大的作用,下面是经过处理后的MyFunc函数的汇编处理内容


_MyFunc    proc    near                            
 push       ebp     ; 将ebp寄存器的值存入栈中         (1)
 mov        ebp,esp ; 将esp寄存器的值存入ebp寄存器中  (2)
 push       456     ; 将456入栈                      (3)
 push       123     ; 将123入栈                      (4)
 call       _AddNum ; 调用 AddNum 函数               (5)
 add        esp,8   ; esp寄存器的值 + 8              (6)
 pop        ebp     ; 读出栈中的数值存入esp寄存器中    (7)
 ret                ; 结束 MyFunc 函数,返回到调用源   (8)
_MyFunc    ebp 


   代码解释中的(1)、(2)、(7)、(8)的处理适用于C语言中的所有函数,我们会在后面展示 AddNum函数处理内容时进行说明。这里希望大家先关注(3)-(6)这一部分,这对了解函数调用机制至关重要。


       (3)和(4)表示的是将传递给AddNum函数的参数通过push入栈。在C语言源代码中,虽然记述为函数AddNum(123, 456),但入栈时则会先按照456, 123这样的顺序。也就是位于后面的数值先入栈。这是C语言的规定。(5)表示的call 指令,会把程序流程跳转到AddNum函数指令的地址处。在汇编语言中,函数名 表示的就是函数所在的内存地址。AddNum 函数处理完毕后,程序流程必须要返回到编号(6)这一行。call 指令运行后,call 指令的下一行(也就指的是(6)这一行)的内存地址(调用函数完毕后要返回的内存地址)会自动的push入栈。该值会在AddNum函数处理的最后通过ret指令pop出栈,然后程序会返回到(6)这一行。


       (6)部分会把栈中存储的两个参数(456和123)进行销毁处理。虽然通过两次的pop指令也可以实现,不过采用esp 寄存器+8的方式会更有效率(处理1次即可)。对栈进行数值的输入和输出时,数值的单位是4字节。因此,通过在负责栈地址管理的esp 寄存器中加上4的2倍8,就可以达到和运行两次 pop命令同样的效果。虽然内存中的数据实际上还残留着,但只要把esp 寄存器的值更新为数据存储地址前面的数据位置,该数据也就相当于销毁了


我在编译 Sample4.c 文件时,出现了下图的这条消息


D: \C> bcc32-c-S Sample4.cBorland C++ 5. 5. 1 for Win32 Copyright <c> 1993.2000
BorlandSample4.c:Warning W8004 Sample4.c 10: 'c' is assigned a value that is 
never used in function MyFunc


上面的意思是指c的值在MyFunc定义了但是一直未被使用,这其实是一项编译器优化的功能,由于存储AddNum函数返回值的变量c在没有被用到,因此编译器就认为 该变量没有意义,进而也就没有生成与之对应的汇编语言代码


下图是调用AddNum这一函数前后栈内存的变化:


目录
相关文章
|
16天前
|
存储 缓存 算法
分布式锁服务深度解析:以Apache Flink的Checkpointing机制为例
【10月更文挑战第7天】在分布式系统中,多个进程或节点可能需要同时访问和操作共享资源。为了确保数据的一致性和系统的稳定性,我们需要一种机制来协调这些进程或节点的访问,避免并发冲突和竞态条件。分布式锁服务正是为此而生的一种解决方案。它通过在网络环境中实现锁机制,确保同一时间只有一个进程或节点能够访问和操作共享资源。
39 3
|
28天前
CPU的工作原理基于其内部结构,通过执行指令来完成各种任务
CPU的工作原理基于其内部结构,通过执行指令来完成各种任务
47 2
|
2月前
|
传感器 C# Android开发
深度解析Uno Platform中的事件处理机制与交互设计艺术:从理论到实践的全方位指南,助您构建响应迅速、交互流畅的跨平台应用
Uno Platform 是一款开源框架,支持使用 C# 和 XAML 开发跨平台原生 UI 应用,兼容 Windows、iOS、Android 及 WebAssembly。本文将介绍 Uno Platform 中高效的事件处理方法,并通过示例代码展示交互设计的核心原则与实践技巧,帮助提升应用的用户体验。事件处理让应用能响应用户输入,如点击、触摸及传感器数据变化。通过 XAML 或 C# 添加事件处理器,可确保及时反馈用户操作。示例代码展示了一个按钮点击事件处理过程。此外,还可运用动画和过渡效果进一步增强应用交互性。
143 57
|
1天前
|
存储 缓存 安全
🌟Java零基础:深入解析Java序列化机制
【10月更文挑战第20天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
9 3
|
6天前
|
Java 开发者 UED
Java编程中的异常处理机制解析
在Java的世界里,异常处理是确保程序稳定性和可靠性的关键。本文将深入探讨Java的异常处理机制,包括异常的类型、如何捕获和处理异常以及自定义异常的创建和使用。通过理解这些概念,开发者可以编写更加健壮和易于维护的代码。
中断处理机制解析
【10月更文挑战第5天】中断处理需定义中断处理函数`irq_handler_t`,参数包括中断信号`irq`和通用指针`dev_id`。返回值`IRQ_NONE`表示非本设备中断,`IRQ_HANDLED`表示已处理,`IRQ_WAKE_THREAD`表示需唤醒等待进程。处理程序常分上下半部,关键部分在中断处理函数中完成,延迟部分通过工作队列处理。注册中断处理函数需调用`request_irq`,参数包括中断信号、处理函数、标志位、设备名和通用指针。
|
2月前
|
移动开发 Android开发 数据安全/隐私保护
移动应用与系统的技术演进:从开发到操作系统的全景解析随着智能手机和平板电脑的普及,移动应用(App)已成为人们日常生活中不可或缺的一部分。无论是社交、娱乐、购物还是办公,移动应用都扮演着重要的角色。而支撑这些应用运行的,正是功能强大且复杂的移动操作系统。本文将深入探讨移动应用的开发过程及其背后的操作系统机制,揭示这一领域的技术演进。
本文旨在提供关于移动应用与系统技术的全面概述,涵盖移动应用的开发生命周期、主要移动操作系统的特点以及它们之间的竞争关系。我们将探讨如何高效地开发移动应用,并分析iOS和Android两大主流操作系统的技术优势与局限。同时,本文还将讨论跨平台解决方案的兴起及其对移动开发领域的影响。通过这篇技术性文章,读者将获得对移动应用开发及操作系统深层理解的钥匙。
|
1月前
|
JSON JavaScript 前端开发
Javaweb中Vue指令的详细解析与应用
Vue指令提供了一种高效、声明式的编码方式,使得开发者可以更专注于数据和业务逻辑,而不是DOM操作的细节。通过熟练使用Vue指令,可以极大地提高开发效率和项目的可维护性。
15 3
|
12天前
|
JavaScript 前端开发 开发者
原型链深入解析:JavaScript中的核心机制
【10月更文挑战第13天】原型链深入解析:JavaScript中的核心机制
22 0
|
2月前
|
存储 关系型数据库 MySQL
深入解析MySQL数据存储机制:从表结构到物理存储
深入解析MySQL数据存储机制:从表结构到物理存储
47 1

推荐镜像

更多