存档在 2013年3月19日

内存区划分

2013年3月19日

一. 在C中分为这几个存储区
1. – 由编译器自动分配释放;
2. – 一般由程序员分配释放,若程序员不释放,程序结束时可能由操作系统回收;
3.全局区(静态区),全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。- 程序结束释放
4.常量区,专门放常量的地方。- 程序结束释放

在函数体中定义的变量通常是在栈上,用malloc, calloc, realloc等分配内存的函数分配得到的就是在堆上。在所有函数体外定义的是全局量,加了static修饰符后不管在哪里都存放在全局区(静态区),在所有函数体外定义的static变量表示在该文件中有效,不能extern到别的文件用,在函数体内定义的static表示只在该函数体内有效。另外,函数中的”adgfdf”这样的字符串存放在常量区。比如: » 阅读更多: 内存区划分

用户态与核心态

2013年3月19日

386及以上的CPU实现了4个特权级模式(WINDOWS只用到了其中两个),其中特权级0(Ring0)是留给操作系统代码,设备驱动程序代码使用的,它们工作于系统核心态;而特权极3(Ring3)则给普通的用户程序使用,它们工作在用户态。运行于处理器核心态的代码不受任何的限制,可以自由地访问任何有效地址,进行直接端口访问。而运行于用户态的代码则要受到处理器的诸多检查,它们只能访问映射其地址空间的页表项中规定的在用户态下可访问页面的虚拟地址,且只能对任务状态段(TSS)中I/O许可位图(I/O Permission Bitmap)中规定的可访问端口进行直接访问(此时处理器状态和控制标志寄存器EFLAGS中的IOPL通常为0,指明当前可以进行直接I/O的最低特权级别是Ring0)。以上的讨论只限于保护模式操作系统,象DOS这种实模式操作系统则没有这些概念,其中的所有代码都可被看作运行在核心态。既然运行在核心态有如此之多的优势,那么病毒当然没有理由不想得到Ring0。处理器模式从Ring3向Ring0的切换发生在控制权转移时,有以下两种情况:访问调用门的长转移指令CALL,访问中断门或陷阱门的INT指令。具体的转移细节由于涉及复杂的保护检查和堆栈切换,不再赘述,请参阅相关资料。现代的操作系统通常使用中断门来提供系统服务,通过执行一条陷入指令来完成模式切换,在INTEL X86上这条指令是INT,如在WIN9X下是INT30(保护模式回调),在LINUX下是INT80,在WINNT/2000下是INT2E。用户模式的服务程序(如系统DLL)通过执行一个INTXX来请求系统服务,然后处理器模式将切换到核心态,工作于核心态的相应的系统代码将服务于此次请求并将结果传给用户程序。

用户态又称目态,核心态又称管态
在X86下,可以理解成ring3 和 ring 0
用户态权限低,无权调用一些核心态才能调用的指令

这是两种内存保护态,一个进程4G地址空间中的每一页均被标记出它是否是处于核心态,所有系统地址空间中的页是核心态,用户空间中的页则为用户态。
访问标记为核心页的的唯一途径是运行在核心态,而只有操作系统和设备驱动才能运行在核心态。
因此一个应用程序不能使自己运行在核心态中,这样为应用程序和操作系统提供了内存保护的坚固级别。用户态怎么修改都不能让系统崩溃。当然应用程序可以通过加载设备驱动进入核心态,去修改系统数据。

[C++]Bridge设计模式

2013年3月19日

Bridge模式定义 :
将抽象和行为划分开来,各自独立,但能动态的结合。

任何事物对象都有抽象和行为之分,例如人,人是一种抽象,人分男人和女人等;人有行为,行为也有各种具体表现,所以,“人”与“人的行为”两个概念也反映了抽象和行为之分。

在面向对象设计的基本概念中,对象这个概念实际是由属性和行为两个部分组成的,属性我们可以认为是一种静止的,是一种抽象,一般情况下,行为是包含在一个对象中,但是,在有的情况下,我们需要将这些行为也进行归类,形成一个总的行为接口,这就是桥模式的用处。

为什么使用?
不希望抽象部分和行为有一种固定的绑定关系,而是应该可以动态联系的

如果一个抽象类或接口有多个具体实现(子类、concrete subclass),这些子类之间关系可能有以下两种情况:
1. 这多个子类之间概念是并列的,如举例,打桩,有两个实例:方形桩和圆形桩;这两个形状上的桩是并列的,没有概念上的重复。

2.这多个子类之中有内容概念上重叠.那么需要我们把抽象共同部分行为共同部分各自独立开来,原来是准备放在一个接口里,现在需要设计两个接口:抽象接口和行为接口,分别放置抽象和行为.

例如,一杯咖啡为例,子类实现类为四个:中杯加奶、大杯加奶、 中杯不加奶、大杯不加奶。

但是,我们注意到:上面四个子类中有概念重叠,可从另外一个角度进行考虑,这四个类实际是两个角色的组合:抽象 和行为,其中抽象为:中杯和大杯;行为为:加奶 不加奶(如加橙汁 加苹果汁).

实现四个子类在抽象和行为之间发生了固定的绑定关系,如果以后动态增加加葡萄汁的行为,就必须再增加两个类:中杯加葡萄汁和大杯加葡萄汁。显然混乱,扩展性极差。

那我们从分离抽象和行为的角度,使用Bridge模式来实现。

如何实现?
以上面提到的咖啡 为例. 我们原来打算只设计一个接口(抽象类),使用Bridge模式后,我们需要将抽象和行为分开,加奶和不加奶属于行为,我们将它们抽象成一个专门的行为接口.

抽象实例数为m,行为数为n,则可以进行m X n次组合。

来看看代码:
CoffeeImp.h

#ifndef _COFFEEIMP_H_
#define _COFFEEIMP_H_
class CoffeeImp
{
public:
	CoffeeImp();
	virtual ~CoffeeImp() = 0;
	virtual void Make();
};

class CoffeeImpSugar : public CoffeeImp
{
public:
	CoffeeImpSugar();
	~CoffeeImpSugar();
	void Make();
};

class CoffeeImpMilk : public CoffeeImp
{
public:
	CoffeeImpMilk();
	~CoffeeImpMilk();
	void Make();
};
#endif

CoffeeImp.cpp

#include "CoffeeImp.h"
#include
using namespace std;

CoffeeImp::CoffeeImp(){}
CoffeeImp::~CoffeeImp(){}
void CoffeeImp::Make(){}

CoffeeImpSugar::CoffeeImpSugar(){}
CoffeeImpSugar::~CoffeeImpSugar(){}
void CoffeeImpSugar::Make()
{
	cout<<"加糖"<<endl;
}

CoffeeImpMilk::CoffeeImpMilk(){}
CoffeeImpMilk::~CoffeeImpMilk(){}
void CoffeeImpMilk::Make()
{
	cout<<"加奶"<<endl;
}

Coffee.h

#ifndef _BRIDGE_H_
#define _BRIDGE_H_
class CoffeeImp;
class Coffee
{
public:
	Coffee();
	virtual ~Coffee() = 0;
	virtual void pourCoffee();
	void setCoffeeImp(CoffeeImp*);

protected:
	CoffeeImp *coffImp;
};

class BigCupCoffee : public Coffee
{
public:
	BigCupCoffee();
	~BigCupCoffee();
	void pourCoffee();
};

class SmallCupCoffee : public Coffee
{
public:
	SmallCupCoffee();
	~SmallCupCoffee();
	void pourCoffee();
};
#endif

Coffee.cpp

#include "Coffee.h"
#include "CoffeeImp.h"
#include "iostream"
using namespace std;

Coffee::Coffee(){}
Coffee::~Coffee(){}
void Coffee::setCoffeeImp(CoffeeImp *imp)
{
	coffImp = imp;
}
void Coffee::pourCoffee(){}

BigCupCoffee::BigCupCoffee(){cout<<"大杯";} 
BigCupCoffee::~BigCupCoffee(){} 
void BigCupCoffee::pourCoffee() 
{
 	coffImp->Make();
}
SmallCupCoffee::SmallCupCoffee(){cout<<"小杯";} 
SmallCupCoffee::~SmallCupCoffee(){} 
void SmallCupCoffee::pourCoffee() 
{
 	coffImp->Make();
}

main.cpp

#include "Coffee.h"
#include "CoffeeImp.h"

#include
using namespace std;

int main()
{
	CoffeeImp* coffeeImp = new CoffeeImpSugar();
	cout<<"Creater1想要:";
 	Coffee*	coffee = new BigCupCoffee(/*coffeeImp*/);
 	coffee->setCoffeeImp(coffeeImp);
	coffee->pourCoffee();
	delete coffeeImp, coffeeImp = 0;
	delete coffee, coffee = 0;
	cout<<"Creater2想要:";
 	coffeeImp = new CoffeeImpMilk();
 	coffee = new SmallCupCoffee();
 	coffee->setCoffeeImp(coffeeImp);
	coffee->pourCoffee();
	delete coffeeImp, coffeeImp = 0;
	delete coffee, coffee = 0;
	return 0;
}

结果为:

Creater1想要:大杯加糖
Creater2想要:小杯加奶