- 博客(137)
- 收藏
- 关注
原创 函数工作原理
一个运行中的程序拥有自己的堆栈空间,堆栈是从高地址向低地址增长的。寄存器ESP始终指向栈顶,初始状态下EBP指向栈底。当EBP指向的地址大于ESP指向的地址时,就形成了栈帧。在32位环境中,每四字节的栈空间保存一个数据,在64位环境中,每八个字节保存一个数据。这里先区分一下程序的栈空间和栈帧。简单来说,程序的栈空间是由程序中的函数的栈帧组成的。我们使用ESP或RSP来管理程序的栈空间,它们始终指向栈顶。
2026-01-02 15:42:32
996
原创 逻辑函数化简与竞争冒险判断
在数字逻辑电路设计中,逻辑函数化简是优化电路性能、降低实现成本的关键技术。通过系统化的化简方法,我们可以将复杂的逻辑表达式转化为最简形式,从而用更少的逻辑门实现相同的功能。本文将深入探讨逻辑函数的标准表达式、代数化简法、卡诺图法以及竞争冒险的识别与消除方法。
2025-12-29 10:47:34
848
原创 数组和指针
当数组作为参数传递的时候,实际上传递的是数组的首地址,在语法上来说传递的是一个指针变量。考虑如上代码,main中的sizeof计算的是数组的长度,getArrLen中的sizeof计算的则是指针的大小,strlen计算的才是数组长度。因为在参数传递的过程中数组首地址变为了一个指针变量。通过反汇编如上代码,我们可以发现在buffer的定义处调用sizeof实际上并没有计算buffer的长度,而是直接传递了一个立即数给printf_s,这是编译器优化的结果。因为buffer的长度在编译期间就可以确定了。
2025-12-16 16:12:46
218
原创 反汇编变量
全局变量和常量有着相似的性质,都是在程序执行之前就存在了。常量在PE的不可写数据节中,全局变量和局部变量在PE的可读可写数据节中。调试该程序时我们发现传递g_num变量的时候,直接传递了一个常数地址。我们用该地址减去模块的加载起始地址,就得到了该变量的相对虚拟地址。通过PE分析工具,我们就可以利用该相对虚拟地址在可执行文件中找到该变量。具有初始值的全局变量,其值在链接时被写入创建的PE文件中,当用户执行该文件时,操作系统先分析这个PE中的数据,将各节中的数据填入对应的虚拟内存地址中。
2025-12-16 15:52:06
356
原创 基本数据类型
我们在分析的时候,会看到不同指令对数据的处理,这时首先要确定数据的存储位置,对于内存中的数据,要查看地址。有了内存地址,才能得到内存属性。我们需要了解的属性有可读、可写、可执行。藉此,可以知道此数据是否为变量(可读写)、是否为常量(只读)、是否为代码(可执行)等。除了知道属性以外,我们还可以考察进程在内存的布局,如栈区、堆区、全局区、代码区等,藉此,又可以知道数据的作用域。行)等。除了知道属性以外,我们还可以考察进程在内存的布局,如栈区、堆区、全局区、代码区等,藉此,又可以知道数据的作用域。
2025-12-07 09:29:45
540
原创 DLL基础
我们首先需要编写该DLL对应的头文件,该头文件可供可执行模块的代码使用,以便于可执行模块使用DLL中的函数和变量。extern__declspec我们使用了MYLIBAPI来修饰头文件中声明的变量和函数。如果在包含该头文件之前没有定义MYLIBAPI宏,那么该宏修饰的变量和函数说明这些对象是在别处定义的,需要导入才可以使用。extern__declspec我们可以看到,在包含MyLib.h头文件之前,定义了MYLIBAPI宏,此时该宏修饰的对象是对外导出使用的。两分代码中的extern "C"
2025-12-04 23:02:23
432
原创 现代处理器的结构特点
为了提高处理器的执行效率和速度,可以把一条指令的执行过程分解成若干个细小的步骤,并分配给相应的单元来完成。各个单元的执行是独立的、并行的。如此一来,各个步骤的执行在时间上就会重叠起来,这种执行指令的方法就是流水线(Pipe-Line)技术。一般来说,流水线的效率受执行时间最长的那一级的限制,要缩短各级的执行时间,就必须让每一级的任务减少,与此同时,就需要把一些复杂的任务再进行分解。
2025-11-28 10:26:03
239
原创 CMOS晶体管
MOS晶体管的三个端子分别称为栅极(gate)、源极(source)、漏记(drain)。通过改变栅极和源极之间的电压值,可以控制源极和漏极之间的电阻R(ds)的大小。左N右P。
2025-11-28 09:17:36
265
原创 实时时钟和CMOS_RAM
计算机可以能够准确的显示时间,依靠着实时时钟电路(RTC)。该电路集成在外围设备控制电路(ICH)中。该电路负责计时。在ICH中,一个静态存储器,称为CMOS RAM。该RAM中保存了日期和时间的数值。
2025-11-28 01:12:17
565
原创 堆结构与堆排序
虽然堆是用完全二叉树表示的,但在使用时通常用一个数组来存储。以数组的下标来标识堆中的节点,并且可以根据下标来获得某一节点的父节点和左右子节点。对于下标为i的节点,其父节点为(i - 1) / 2,其左子节点为2 * i + 1,右子节点为2 * i + 2。我们定义一个节点的高度为从该节点到叶子节点的最长简单向下路径的边数。树的高度就是根节点的高度。对于具有n个元素的数组,将其看作完全二叉树的话,树的高度为lgn。同时可以看到,对于大小为n的堆,n/2为该堆的第一个叶子节点。
2025-11-22 14:28:22
571
原创 COM_QueryInterface
QueryInterface是COM最为重要的部分,一个组件实际上是由QueryInterface定义的。组件所支持的接口集实际上就是QueryInterface能够返回接口指针的那些接口。客户并了解组件的唯一方法就是进行查询。QueryInterface是将COM组件的编写过程同编写C++类的过程区分开来的一种新特性。
2025-11-19 00:51:27
362
原创 COM_接口
接口提供了两个不同对象之间的连接。对于COM来说,接口就是一个包含一个函数指针数组的内存结构。每一个数组元素是组件所实现的函数的地址。在c++中,可以使用抽象基类来实现接口。组件中的接口可能有任意个,一般使用多重继承来实现。
2025-11-19 00:04:23
419
原创 COM组件
一个程序由若干已经编译好的组件组成。当程序需要更新的时候,只需要更新对应的组件就可以了。为了将应用程序拆分为组件,我们就需要使用COM。
2025-11-18 20:01:04
419
原创 leetcode寻找第k大的值
解题思路:该题对时间复杂度要求较高,对整个数组进行排序之后再求解在时间上划不来。只要使得数组局部有序即可。这里采用快速排序的方法找到第k大的元素。
2025-11-15 23:40:36
732
原创 leetcode两数相加
https://leetcode.cn/problems/add-two-numbers/description/]解题思路:把每位数先加到其中一个链表中,再遍历该链表检测每位数是否大于10,大于则下一位加一,该位取个位。
2025-11-14 10:42:03
163
原创 COM_QueryInterface
QueryInterface是COM最为重要的部分,一个组件实际上是由QueryInterface定义的。组件所支持的接口集实际上就是QueryInterface能够返回接口指针的那些接口。客户并了解组件的唯一方法就是进行查询。QueryInterface是将COM组件的编写过程同编写C++类的过程区分开来的一种新特性。
2025-11-10 23:54:12
208
1
原创 COM组件
一个程序由若干已经编译好的组件组成。当程序需要更新的时候,只需要更新对应的组件就可以了。为了将应用程序拆分为组件,我们就需要使用COM。
2025-11-10 23:53:35
219
原创 计算机外设与CPU通信
不同的IO设备的连线数量、传输的信号不一样,而且各自的插头和插孔也千差万别,这该如何让处理器跟它们打交道?I/O接口可以是一个电路板,也可能是一块小芯片,这取决于它有多复杂。无论如何,它是一个典型的变换器,或者说是一个翻译器,在一边,它按处理器的信号规程工作,负责把处理器的信号转换成外围设备能接受的另一种信号;在另一边,它也做同样的工作,把外围设备的信号变换成处理器可以接受的形式。IO接口不可能直接与CPU相连,需要先接在总线上。
2025-11-06 08:22:40
404
原创 记录GDI+保存位图
我做的一个项目上有一个需求:以图片的形式保存当前窗口的内容。刚开始我使用GDI中的函数,手动填充位图的内容,并写入到文件中,不知道由于什么原因,无法保存。遂使用GDI+来保存位图。其中也有许多坑,但最终也实现了该功能。现记录下来,希望对有类似需求的读者有帮助。
2025-11-05 23:43:12
343
原创 元对象系统
Qt 中引入了元对象系统对标准 C++语言进行扩展,增加了信号与槽、属性系统、动态翻译等特性,为编写 GUI 应用程序提供了极大的方便。
2025-10-30 11:06:03
310
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人
RSS订阅