内存空间
程序在执行时,传递给CPU的地址是逻辑地址,由段选择符和偏移量组成。逻辑地址必须映射成线性地址,再映射为物理地址才能访问物理内存。
a.逻辑地址转化为线性地址:逻辑地址以“段寄存器:偏移地址”形式存在,通过段寄存器里的索引找到段基址,再加上段偏移量,得到线性地址。
b.线性地址转化为物理地址:线性地址分为页目录项、页表项和页偏移组成。页目录索引+页目录基址得页表基址,页表基址+页表索引得页基址,页基址+页偏移得物理地址。
程序的内存布局为:全局变量区、静态常量数据、代码区、变量、堆、空闲区、栈区。
堆:由程序员分配和释放,malloc()/free(),new/delete,内存区域不连续(链表),速度较慢。栈:系统自动分配和释放,连续内存空间(栈帧),用于存放函数的参数值、局部变量的值等。
汇编基础
a.CPU由运算器、控制器、寄存器组和内部总线构成。
b.系统总线:包括控制总线、数据总线和地址总线。数据总线双向,用于传送数据信息。地址总线单向,用于传送地址。控制总线双向,用于传送控制信号,如读写、中断响应信号等。
c.寄存器:通用寄存器:EAX,EBX,ECX,EDX;源变址目的变址寄存器:ESI,EDI;栈寄存器:SS,ESP,EBP;代码段寄存器/程序指令寄存器:CS,IP;数据段寄存器:DS;附加段寄存器:ES;标志寄存器:ZF零标志、AF辅助进位标志、PF奇偶标志、SP符号标志、CF进位标志、OF溢出标志
d.汇编指令:MOV,ADD/ADC,SUB/SBB,PUSH/POP,LEA,CMP,JMP,JXX,LOOP,CALL/RET,INT/IRET。
调试方法
a.动态调试:断点、执行、查看。单步执行通过设置程序标志寄存器的TF位来实现,程序从断点处停止,单步跟踪后运行到下一断点处。
b.静态调试:程序或系统崩溃后产生的dump或core文件,进行事后分析。
多线程编程:提高程序的并发度和运行效率
进程:程序的动态执行过程,包括代码加载、执行到执行完毕的完整过程,是资源分配的基本单位。
线程:进程中执行运算的最小单位,是CPU调度运行的基本单位。易于调度、提高并发性、开销少、有利于发挥多处理器的功能。线程运行过程中需要同步与互斥,不同进程的线程间要利用进程通信的办法实现同步。
同步互斥机制
临界区:通过对多线程的串行化来访问公共资源,用来控制数据访问。
互斥量:为协调共同对一个共享资源的单独访问而设计。
信号量:为控制同时访问共享资源的最大线程数目而设计。
事件:用来通知线程有事已发生,从而启动后继任务。
进程间通信方式
共享内存:内存映射文件,通过多个进程映射同一个文件对象的视图来实现,意味着共享物理存储器的同一个页面。
管道:进程通信的特殊文件,分为匿名管道和命名管道。匿名管道用于本地系统中父进程和子进程间的通信,命名管道通过一个名字进行标识,使客户端和服务器端可以通过该管道进行通信。
信号量:一个计数器,用于处理进程或线程临界资源访问的同步问题,临界资源可能是一段代码、一个变量或某个硬件。
共享文件:用于通信的文件被一个进程打开并向其中写数据,而另一个进程则将文件打开从里面读数据。
消息机制:windows操作系统提供的驱动机制,利用消息进行进程通信就是使用消息激活某种操作的过程。