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

本文涉及的产品
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
简介: 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这一函数前后栈内存的变化:


目录
相关文章
|
10天前
|
传感器 C# Android开发
深度解析Uno Platform中的事件处理机制与交互设计艺术:从理论到实践的全方位指南,助您构建响应迅速、交互流畅的跨平台应用
Uno Platform 是一款开源框架,支持使用 C# 和 XAML 开发跨平台原生 UI 应用,兼容 Windows、iOS、Android 及 WebAssembly。本文将介绍 Uno Platform 中高效的事件处理方法,并通过示例代码展示交互设计的核心原则与实践技巧,帮助提升应用的用户体验。事件处理让应用能响应用户输入,如点击、触摸及传感器数据变化。通过 XAML 或 C# 添加事件处理器,可确保及时反馈用户操作。示例代码展示了一个按钮点击事件处理过程。此外,还可运用动画和过渡效果进一步增强应用交互性。
113 57
|
4天前
|
Java 开发者
Java中的异常处理机制深度解析
在Java编程中,异常处理是保证程序稳定性和健壮性的重要手段。本文将深入探讨Java的异常处理机制,包括异常的分类、捕获与处理、自定义异常以及一些最佳实践。通过详细讲解和代码示例,帮助读者更好地理解和应用这一机制,提升代码质量。
9 1
|
4天前
|
JavaScript 前端开发 UED
Javaweb中Vue指令的详细解析与应用
Vue指令是Vue框架中非常强大的特性之一,它提供了一种简洁、高效的方式来增强HTML元素和组件的功能。通过合理使用这些指令,可以使你的JavaWeb应用更加响应用户的操作,提高交互性和用户体验。而且,通过创建自定义指令,你可以进一步扩展Vue的功能,使其更贴合你的应用需求。
9 1
|
10天前
|
存储 缓存 Android开发
Android RecyclerView 缓存机制深度解析与面试题
本文首发于公众号“AntDream”,详细解析了 `RecyclerView` 的缓存机制,包括多级缓存的原理与流程,并提供了常见面试题及答案。通过本文,你将深入了解 `RecyclerView` 的高性能秘诀,提升列表和网格的开发技能。
33 8
|
14天前
|
Java 程序员 开发者
Java中的异常处理机制深度解析
本文旨在深入探讨Java中异常处理的核心概念与实际应用,通过剖析异常的本质、分类、捕获及处理方法,揭示其在程序设计中的关键作用。不同于常规摘要,本文将直接切入主题,以简明扼要的方式概述异常处理的重要性及其在Java编程中的应用策略,引导读者快速把握异常处理的精髓。
|
12天前
|
安全 Java 开发者
Java并发编程中的锁机制解析
本文深入探讨了Java中用于管理多线程同步的关键工具——锁机制。通过分析synchronized关键字和ReentrantLock类等核心概念,揭示了它们在构建线程安全应用中的重要性。同时,文章还讨论了锁机制的高级特性,如公平性、类锁和对象锁的区别,以及锁的优化技术如锁粗化和锁消除。此外,指出了在高并发环境下锁竞争可能导致的问题,并提出了减少锁持有时间和使用无锁编程等策略来优化性能的建议。最后,强调了理解和正确使用Java锁机制对于开发高效、可靠并发应用程序的重要性。
16 3
|
16天前
|
Java 开发者
深入解析Java中的异常处理机制
本文将深入探讨Java中异常处理的核心概念和实际应用,包括异常的分类、捕获、处理以及最佳实践。我们将通过具体示例展示如何有效使用try-catch块、throws关键字和自定义异常类,以帮助读者更好地理解和应用Java异常处理机制。
12 1
|
17天前
|
Java 程序员 开发者
Java中的异常处理机制深度解析
本文旨在深入探讨Java中异常处理的机制,包括异常的分类、如何捕获和处理异常,以及自定义异常的最佳实践。通过实例讲解,帮助读者更好地理解如何在Java编程中有效管理和利用异常处理来提高代码的健壮性和可维护性。
|
20天前
|
KVM 虚拟化
计算虚拟化之CPU——qemu解析
【9月更文挑战10天】本文介绍了QEMU命令行参数的解析过程及其在KVM虚拟化中的应用。展示了QEMU通过多个`qemu_add_opts`函数调用处理不同类型设备和配置选项的方式,并附上了OpenStack生成的一个复杂KVM参数实例。
中断处理机制解析
【9月更文挑战第23天】中断处理需定义中断处理函数`irq_handler_t`,参数包括中断信号`irq`和通用指针`dev_id`。返回值`IRQ_NONE`表示非本设备中断,`IRQ_HANDLED`表示已处理,`IRQ_WAKE_THREAD`表示需唤醒等待进程。处理程序常分上下半部,关键部分在中断处理函数中完成,延迟部分通过工作队列处理。注册中断处理函数需调用`request_irq`,参数包括中断信号、处理函数、标志位、设备名和通用指针。

热门文章

最新文章

推荐镜像

更多
下一篇
无影云桌面