当前位置:  编程技术>移动开发
本页文章导读:
    ▪NSString+NSMutableString+NSValue+NSAraay用法集锦        NSString+NSMutableString+NSValue+NSAraay用法汇总/*******************************************************************************************      NSString ****************************************************************************************.........
    ▪ 保护模式准备知识-书中pmtest9中断机制代码详细注释        保护模式预备知识--书中pmtest9中断机制代码详细注释 一、80386,内存,8255A的连接如图1                                                                                          .........
    ▪ delegate为何用弱引用       delegate为什么用弱引用比如在A页面设置B的delegate为A的实例,  // A.m中某处 B* b = [B alloc] init]; b.delegate = self; [self.view addSubview:b]; [b release]; 那么 1.是A负责创建B的,A的生命周期一定比B要长(B存.........

[1]NSString+NSMutableString+NSValue+NSAraay用法集锦
    来源: 互联网  发布时间: 2014-02-18
NSString+NSMutableString+NSValue+NSAraay用法汇总
/*******************************************************************************************
     NSString
*******************************************************************************************/
   
    /*----------------创建字符串的方法----------------*/

    //1、创建常量字符串。
    NSString *astring = @"This is a String!";

    //2、创建空字符串,给予赋值。
    NSString *astring = [[NSString alloc] init];
    astring = @"This is a String!";
    NSLog(@"astring:%@", astring);
    [astring release];

    //3、在以上方法中,提升速度:initWithString方法
    NSString *astring = [[NSString alloc] initWithString:@"This is a String!"];
    NSLog(@"astring:%@", astring);
    [astring release];

    //4、用标准c创建字符串:initWithCString方法
    char *Cstring = "This is a String!";
    NSString *astring = [[NSString alloc] initWithCString:Cstring];
    NSLog(@"astring:%@",astring);
    [astring release];

    //5、创建格式化字符串:占位符(由一个%加一个字符组成)
    int i = 1;
    int j = 2;
    NSString *astring = [[NSString alloc] initWithString:[NSString stringWithFormat:@"%d.This is %i string!", i, j]];
    NSLog(@"astring:%@", astring);
    [astring release];

    //6、创建临时字符串
    NSString *astring;
    astring = [NSString stringWithCString:"This is a temporary string"];
    NSLog(@"astring:%@", astring);

    /*----------------从文件读取字符串:initWithContentsOfFile方法----------------*/    
    NSString *path = @"astring.text";
    NSString *astring = [[NSString alloc] initWithContentsOfFile:path];
    NSLog(@"astring:%@",astring);
    [astring release];

    /*----------------写字符串到文件:writeToFile方法----------------*/    
    NSString *astring = [[NSString alloc] initWithString:@"This is a String!"];
    NSLog(@"astring:%@",astring);
    NSString *path = @"astring.text";    
    [astring writeToFile: path atomically: YES];
    [astring release];    

    /*----------------比较两个字符串----------------*/        

    // 1、用C比较:strcmp函数
    char string1[] = "string!";
    char string2[] = "string!";
    if(strcmp(string1, string2) = = 0)
    {
        NSLog(@"1");
    }

    // 2、isEqualToString方法    
    NSString *astring01 = @"This is a String!";
    NSString *astring02 = @"This is a String!";
    BOOL result = [astring01 isEqualToString:astring02];
    NSLog(@"result:%d",result);

    // 3、compare方法(comparer返回的三种值)  

  

    // 1) NSOrderedSame判断两者内容是否相同

    NSString *astring01 = @"This is a String!";
    NSString *astring02 = @"This is a String!";    
    BOOL result = [astring01 compare:astring02] = = NSOrderedSame;    

    NSLog(@"result:%d",result);  


    // 2) NSOrderedAscending判断两对象值的大小(按字母顺序进行比较,astring02大于astring01为真)

    NSString *astring01 = @"This is a String!";
    NSString *astring02 = @"this is a String!";
    BOOL result = [astring01 compare:astring02] = = NSOrderedAscending;    
    NSLog(@"result:%d",result);

    // 3) NSOrderedDescending判断两对象值的大小(按字母顺序进行比较,astring02小于astring01为真)
    NSString *astring01 = @"this is a String!";
    NSString *astring02 = @"This is a String!";
    BOOL result = [astring01 compare:astring02] = = NSOrderedDescending;    
    NSLog(@"result:%d",result);     

    // 4、不考虑大小写比较字符串1
    NSString *astring01 = @"this is a String!";
    NSString *astring02 = @"This is a String!";
    BOOL result = [astring01 caseInsensitiveCompare:astring02] = = NSOrderedSame;    
    NSLog(@"result:%d",result);     
    // NSOrderedDescending判断两对象值的大小(按字母顺序进行比较,astring02小于astring01为真)

    // 5、不考虑大小写比较字符串2
    NSString *astring01 = @"this is a String!";
    NSString *astring02 = @"This is a String!";
    BOOL result = [astring01 compare:astring02
                            options:NSCaseInsensitiveSearch | NSNumericSearch] = = NSOrderedSame;    
    NSLog(@"result:%d",result);     
    // NSCaseInsensitiveSearch:不区分大小写比较 NSLiteralSearch:进行完全比较,区分大小写 NSNumericSearch:比较字符串的字符个数,而不是字符值。


    /*----------------改变字符串的大小写----------------*/    

    NSString *string1 = @"A String"; 
    NSString *string2 = @"String"; 
    NSLog(@"string1:%@",[string1 uppercaseString]);//大写
    NSLog(@"string2:%@",[string2 lowercaseString]);//小写
    NSLog(@"string2:%@",[string2 capitalizedString]);//首字母大小


    /*----------------在串中搜索子串----------------*/        

    NSString *string1 = @"This is a string";
    NSString *string2 = @"string";
    NSRange range = [string1 rangeOfString:string2];
    int location = range.location;
    int leight = range.length;
    NSString *astring = [[NSString alloc] initWithString:[NSString stringWithFormat:@"Location:%i,Leight:%i",location,leight]];
    NSLog(@"astring:%@",astring);
    [astring release];


    /*----------------抽取子串 ----------------*/        

    // -substringToIndex: 从字符串的开头一直截取到指定的位置,但不包括该位置的字符
    NSString *string1 = @"This is a string";
    NSString *string2 = [string1 substringToIndex:3];
    NSLog(@"string2:%@",string2);

    // -substringFromIndex: 以指定位置开始(包括指定位置的字符),并包括之后的全部字符
    NSString *string1 = @"This is a string";
    NSString *string2 = [string1 substringFromIndex:3];
    NSLog(@"string2:%@",string2);

    // -substringWithRange: //按照所给出的位置,长度,任意地从字符串中截取子串
    NSString *string1 = @"This is a string";
    NSString *string2 = [string1 substringWithRange:NSMakeRange(0, 4)];
    NSLog(@"string2:%@",string2);

    //扩展路径
    NSString *Path = @"~/NSData.txt";
    NSString *absolutePath = [Path stringByExpandingTildeInPath];
    NSLog(@"absolutePath:%@",absolutePath);
    NSLog(@"Path:%@",[absolutePath stringByAbbreviatingWithTildeInPath]);

    //文件扩展名
    NSString *Path = @"~/NSData.txt";
    NSLog(@"Extension:%@",[Path pathExtension]);



/*******************************************************************************************
NSMutableString
*******************************************************************************************/    

    /*----------------给字符串分配容量----------------*/
    //stringWithCapacity:
    NSMutableString *String;
    String = [NSMutableString stringWithCapacity:40];


    /*----------------在已有字符串后面添加字符----------------*/    

    //appendString: and appendFormat:

    NSMutableString *String1 = [[NSMutableString alloc] initWithString:@"This is a NSMutableString"];
    //[String1 appendString:@", I will be adding some character"];
    [String1 appendFormat:[NSString stringWithFormat:@", I will be adding some character"]];
    NSLog(@"String1:%@",String1);
    */


    /*----------------在已有字符串中按照所给出范围和长度删除字符------*/    
    /*
     //deleteCharactersInRange:
     NSMutableString *String1 = [[NSMutableString alloc] initWithString:@"This is a NSMutableString"];
     [String1 deleteCharactersInRange:NSMakeRange(0, 5)];
     NSLog(@"String1:%@",String1);

    /*----------------在已有字符串后面在所指定的位置中插入给出的字符串------*/


    // -insertString: atIndex:
    NSMutableString *String1 = [[NSMutableString alloc] initWithString:@"This is a NSMutableString"];
    [String1 insertString:@"Hi! " atIndex:0];
    NSLog(@"String1:%@",String1);

    /*----------------将已有的空符串换成其它的字符串------*/

    //-setString:
    NSMutableString *String1 = [[NSMutableString alloc] initWithString:@"This is a NSMutableString"];
    [String1 setString:@"Hello Word!"];
    NSLog(@"String1:%@",String1);

    /*----------------按照所给出的范围,和字符串替换的原有的字符------*/

    //-setString:
    NSMutableString *String1 = [[NSMutableString alloc] initWithString:@"This is a NSMutableString"];
    [String1 replaceCharactersInRange:NSMakeRange(0, 4) withString:@"That"];
    NSLog(@"String1:%@",String1);

    /*----------------判断字符串内是否还包含别的字符串(前缀,后缀)-------------*/
    // 01:检查字符串是否以另一个字符串开头- (BOOL) hasPrefix: (NSString *) aString;
    NSString *String1 = @"NSStringInformation.txt";
    [String1 hasPrefix:@"NSString"] = = 1 ?  NSLog(@"YES") : NSLog(@"NO");
    [String1 hasSuffix:@".txt"] = = 1 ?  NSLog(@"YES") : NSLog(@"NO");

    // 02:查找字符串某处是否包含其它字符串 - (NSRange) rangeOfString: (NSString *) aString,这一点前面在串中搜索子串用到过;



 /*******************************************************************************************
     NSArray
 *******************************************************************************************/

    /*----------------创建数组---------------------*/
    // NSArray *array = [[NSArray alloc] initWithObjects:
    @"One",@"Two",@"Three",@"Four",nil];

    self.dataArray = array;
    [array release];

    // - (unsigned) Count;数组所包含对象个数;
    NSLog(@"self.dataArray cound:%d",[self.dataArray count]);

    // - (id) objectAtIndex: (unsigned int) index;获取指定索引处的对象;
    NSLog(@"self.dataArray cound 2:%@",[self.dataArray objectAtIndex:2]);


    /*----------------从一个数组拷贝数据到另一数组(可变数级)-----------------------*/    

    // arrayWithArray:
    // NSArray *array1 = [[NSArray alloc] init];
    NSMutableArray *MutableArray = [[NSMutableArray alloc] init];
    NSArray *array = [NSArray arrayWithObjects:
                      @"a",@"b",@"c",nil];
    NSLog(@"array:%@",array);
    MutableArray = [NSMutableArray arrayWithArray:array];
    NSLog(@"MutableArray:%@",MutableArray);

    array1 = [NSArray arrayWithArray:array];
    NSLog(@"array1:%@",array1);


    // Copy

    // id obj;
    NSMutableArray *newArray = [[NSMutableArray alloc] init];
    NSArray *oldArray = [NSArray arrayWithObjects:
                         @"a",@"b",@"c",@"d",@"e",@"f",@"g",@"h",nil];

    NSLog(@"oldArray:%@",oldArray);
    for(int i = 0; i < [oldArray count]; i++)
    {        
        obj = [[oldArray objectAtIndex:i] copy];
        [newArray addObject: obj];
    }
    //     
    NSLog(@"newArray:%@", newArray);
    [newArray release];


    // 快速枚举

    // NSMutableArray *newArray = [[NSMutableArray alloc] init];
    NSArray *oldArray = [NSArray arrayWithObjects:
                         @"a",@"b",@"c",@"d",@"e",@"f",@"g",@"h",nil];    
    NSLog(@"oldArray:%@",oldArray);

    for(id obj in oldArray)
    {
        [newArray addObject: obj];
    }
    //     
    NSLog(@"newArray:%@", newArray);
    [newArray release];    


    // Deep copy

    // NSMutableArray *newArray = [[NSMutableArray alloc] init];
    NSArray *oldArray = [NSArray arrayWithObjects:
                         @"a",@"b",@"c",@"d",@"e",@"f",@"g",@"h",nil];    
    NSLog(@"oldArray:%@",oldArray);    
    newArray = (NSMutableArray*)CFPropertyListCreateDeepCopy(kCFAllocatorDefault, (CFPropertyListRef)oldArray, kCFPropertyListMutableContainers);
    NSLog(@"newArray:%@", newArray);
    [newArray release];    


    // Copy and sort

    // NSMutableArray *newArray = [[NSMutableArray alloc] init];
    NSArray *oldArray = [NSArray arrayWithObjects:
                         @"b",@"a",@"e",@"d",@"c",@"f",@"h",@"g",nil];    
    NSLog(@"oldArray:%@",oldArray);
    NSEnumerator *enumerator;
    enumerator = [oldArray objectEnumerator];
    id obj;
    while(obj = [enumerator nextObject])
    {
        [newArray addObject: obj];
    }
    [newArray sortUsingSelector:@selector(compare:)];
    NSLog(@"newArray:%@", newArray);
    [newArray release];


    /*----------------切分数组------------------------------*/

    //从字符串分割到数组- componentsSeparatedByString:
    NSString *string = [[NSString alloc] initWithString:@"One,Two,Three,Four"];
    NSLog(@"string:%@",string);    
    NSArray *array = [string componentsSeparatedByString:@","];
    NSLog(@"array:%@",array);
    [string release];


    //从数组合并元素到字符串- componentsJoinedByString:
    NSArray *array = [[NSArray alloc] initWithObjects:@"One",@"Two",@"Three",@"Four",nil];
    NSString *string = [array componentsJoinedByString:@","];
    NSLog(@"string:%@",string);


    /*******************************************************************************************
     NSMutableArray
     *******************************************************************************************/
    /*----------------给数组分配容量----------------*/
    //NSArray *array;

    array = [NSMutableArray arrayWithCapacity:20];


    /*----------------在数组末尾添加对象----------------*/
    //- (void) addObject: (id) anObject;
    //NSMutableArray *array = [NSMutableArray arrayWithObjects:
    @"One",@"Two",@"Three",nil];
    [array addObject:@"Four"];
    NSLog(@"array:%@",array);

    /*----------------删除数组中指定索引处对象----------------*/    
    //-(void) removeObjectAtIndex: (unsigned) index;    
    //NSMutableArray *array = [NSMutableArray arrayWithObjects:
    @"One",@"Two",@"Three",nil];
    [array removeObjectAtIndex:1];
    NSLog(@"array:%@",array);

    /*----------------数组枚举---------------*/    
    //- (NSEnumerator *)objectEnumerator;从前向后
    //NSMutableArray *array = [NSMutableArray arrayWithObjects:
    @"One",@"Two",@"Three",nil];
    NSEnumerator *enumerator;
    enumerator = [array objectEnumerator];

    id thingie;

    while (thingie = [enumerator nextObject]) 

    {

        NSLog(@"thingie:%@",thingie);
    }


    // - (NSEnumerator *)reverseObjectEnumerator;从后向前
    //NSMutableArray *array = [NSMutableArray arrayWithObjects:
    @"One",@"Two",@"Three",nil];
    NSEnumerator *enumerator;
    enumerator = [array reverseObjectEnumerator];

    id object;
    while (object = [enumerator nextObject]) {
        NSLog(@"object:%@",object);
    }


    //快速枚举
    //NSMutableArray *array = [NSMutableArray arrayWithObjects:
    @"One",@"Two",@"Three",nil];
    for(NSString *string in array)
    {
        NSLog(@"string:%@",string);
    }



  /*******************************************************************************************
     NSDictionary
  *******************************************************************************************/

    /*----------------创建字典------------------------------------*/
    //- (id) initWithObjectsAndKeys;

    //NSDictionary *dictionary = [[NSDictionary alloc] initWithObjectsAndKeys:@"One",@"1",@"Two",@"2",@"Three",@"3",nil];
    NSString *string = [dictionary objectForKey:@"One"];
    NSLog(@"string:%@",string);
    NSLog(@"dictionary:%@",dictionary);
    [dictionary release];


    /*******************************************************************************************
     NSMutableDictionary
     *******************************************************************************************/

    /*----------------创建可变字典------------------------------------*/    
    //创建
    NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];

    //添加字典
    [dictionary setObject:@"One" forKey:@"1"];
    [dictionary setObject:@"Two" forKey:@"2"];
    [dictionary setObject:@"Three" forKey:@"3"];
    [dictionary setObject:@"Four" forKey:@"4"];
    NSLog(@"dictionary:%@",dictionary);

    //删除指定的字典
    [dictionary removeObjectForKey:@"3"];
    NSLog(@"dictionary:%@",dictionary);


    /*******************************************************************************************
     NSValue(对任何对象进行包装)
     *******************************************************************************************/

    /*----------------将NSRect放入NSArray中------------------------------------*/    
    //将NSRect放入NSArray中
    NSMutableArray *array = [[NSMutableArray alloc] init];
    NSValue *value;
    CGRect rect = CGRectMake(0, 0, 320, 480);    
    value = [NSValue valueWithBytes:&rect objCType:@encode(CGRect)];
    [array addObject:value];
    NSLog(@"array:%@",array);

    //从Array中提取
    value = [array objectAtIndex:0];
    [value getValue:&rect];
    NSLog(@"value:%@",value);


    /*******************************************************************************************
     从目录搜索扩展名为jpg的文件
     *******************************************************************************************/

    //NSFileManager *fileManager = [NSFileManager defaultManager];
    NSString *home;
    home = @"../Users/";

    NSDirectoryEnumerator *direnum;
    direnum = [fileManager enumeratorAtPath: home];

    NSMutableArray *files = [[NSMutableArray alloc] init];

    //枚举
    NSString *filename;
    while (filename = [direnum nextObject]) {
        if([[filename pathExtension] hasSuffix:@"jpg"]){
            [files addObject:filename];
        }
    }

    //快速枚举
    //for(NSString *filename in direnum)
    //{
    //    if([[filename pathExtension] isEqualToString:@"jpg"]){
    //        [files addObject:filename];
    //    }
    //}
    NSLog(@"files:%@",files);

    //枚举
    NSEnumerator *filenum;
    filenum = [files objectEnumerator];
    while (filename = [filenum nextObject]) {
        NSLog(@"filename:%@",filename);
    }

    
[2] 保护模式准备知识-书中pmtest9中断机制代码详细注释
    来源: 互联网  发布时间: 2014-02-18
保护模式预备知识--书中pmtest9中断机制代码详细注释

 一、80386,内存,8255A的连接如图1

            

                                                                            图 1               


二、编程8255A中断控制器(将ICW写入特定的寄存器)

       8255A是可编程中断控制器,对它的设置并不复杂,是通过向相对应的端口写入特定的ICW(Initialization Command Word)来实现的。主8259A对应的端口地址是20h和21h,从8259A对应的端口地址是A0h和A1h。ICW共有4个,每一个都是具有特定格式的字节,为了先对初始化8259A的过程有一个概括的了解,我们过一会再来关注每一个ICW的格式,现在,先来看一下初始化过程:

       1、往端口20h(主片)或A0h(从片)写入ICW1。

       2、往端口21h(主片)或A1h(从片)写入ICW2。

       3、往端口21h(主片)或A1h(从片)写入ICW3。

       4、往端口21h(主片)或A1h(从片)写入ICW4。


       ICW格式如图2:

       

       

         

                                                       图 2 ICW的格式                                  图 3 OCW1

       若想屏蔽或者打开外部中断,只需要往8259A写入OCW1就可以了,即写入中断屏蔽寄存器(IMR),OCW1的格式如图3。

       可屏蔽中断与NMI的区别在于是否受到IF位的影响,而8259A的中断屏蔽寄存器(IMR)也影响着中断是否会被响应。所以,外部可屏蔽中断的发生就会受到两个因素的影响,只有当IF位为1,并且IMR相应位为0时才会发生。除单步中断外,所有内部中断都无法禁止,即不能通过CLI指令使IF=0,使其不响应。


三、保护模式下的中断

       1、0-19的中断和异常已经安排好了,如书上89页表3.8


       2、有特权级变化时,中断堆栈变化如图4。从中断或异常返回时必须使用指令iretd,它和ret很相似,只是它同时会改变eflags的值。需要注意的是,只有当CPL为0时,eflags中的IOPL域才会改变,而且只有当CPL小于等于IOPL时,IF才会被改变。另外,iretd执行时Error Code不会被自动从堆栈弹出,所以执行它之前要先将它从栈中清除掉。指令in、ins、out、outs、cli、sti只有在CPL小于等于IOPL时才能执行。这些指令被称为I/O敏感指令。如果低特权级的指令试图访问这些I/O敏感指令将会导致常规保护错误(#GP)。

       

                                                       图 4 中断或异常发生时的堆栈


       3、I/O许可位

       TSS偏移102字节处有一个被称做"I/O许可位图基址"的东西,它是一个以TSS的地址为首地址的偏移,指向的便是I/O许可位图。之所以叫做位图,是因为它的每一位表示一个字节的端口地址是否可用。如果某一位为0,则表示此位对应的端口号可用,为1则不可用。由于每一个任务都可以有单独的TSS,所以每个任务可以有它单独的I/O许可位图。


       4、保护模式下中断执行过程

      以下由硬件自动完成:

      ①从中断信息中取得中断类型码。

      ②标志寄存器eflags的值入栈,因为在中断过程中要改变标志寄存器的值,所以先将其保存在栈中。

      ③设置标志寄存器IF和TF位为0,为了防止在此中断中再来其他外部中断。

      ④cs,eip,error code入栈。

      ⑤根据中断类型码在IDT中找到中断门执行代码。

      IRETD 指令先弹出一个32位的EIP值,然后再弹出一个32位值并将最低的2个字节值传入CS寄存器,最后再弹出一个32位的标志寄存器值。


      pmtest9.asm代码如下:

%include	"pm.inc"	; 常量, 宏, 以及一些说明

org	07c00h
	jmp	LABEL_BEGIN

[SECTION .gdt]
; GDT
;                              段基址,       段界限     , 属性
LABEL_GDT:	   Descriptor       0,                0, 0           ; 空描述符
LABEL_DESC_NORMAL:	Descriptor	       0,            0ffffh, DA_DRW			; Normal 描述符
LABEL_DESC_CODE32: Descriptor       0, SegCode32Len - 1, DA_C + DA_32; 非一致代码段
LABEL_DESC_CODE16:	Descriptor	       0,            0ffffh, DA_C			; 非一致代码段, 16
LABEL_DESC_VIDEO:  Descriptor 0B8000h,           0ffffh, DA_DRW	     ; 显存首地址
; GDT 结束

GdtLen		equ	$ - LABEL_GDT	; GDT长度
GdtPtr		dw	GdtLen - 1	; GDT界限
		dd	0		; GDT基地址

; GDT 选择子
SelectorNormal		equ	LABEL_DESC_NORMAL	- LABEL_GDT
SelectorCode32		equ	LABEL_DESC_CODE32	- LABEL_GDT
SelectorCode16		equ	LABEL_DESC_CODE16	- LABEL_GDT
SelectorVideo		equ	LABEL_DESC_VIDEO	- LABEL_GDT
; END of [SECTION .gdt]

[SECTION .data1]	 ; 数据段
ALIGN	32
[BITS	32]
LABEL_DATA:
; 实模式下使用这些符号
; 变量
_wSPValueInRealMode		dw	0
_SavedIDTR:			dd	0	; 用于保存 IDTR
				dd	0
_SavedIMREG:			db	0	; 中断屏蔽寄存器值


DataLen			equ	$ - LABEL_DATA
; END of [SECTION .data1]


; IDT
[SECTION .idt]
ALIGN	32
[BITS	32]
LABEL_IDT:;最多256个中断门,每个占8个字节,所以IDT最大占2K。前面20个已被占用。
; 门                目标选择子,            偏移, DCount, 属性
%rep 32               
		Gate	SelectorCode32, SpuriousHandler,      0, DA_386IGate
%endrep
.020h:		Gate	SelectorCode32,    ClockHandler,      0, DA_386IGate   ;转换成10进制是32
%rep 95
		Gate	SelectorCode32, SpuriousHandler,      0, DA_386IGate
%endrep
.080h:		Gate	SelectorCode32,  UserIntHandler,      0, DA_386IGate ;转换为10进制是128

IdtLen		equ	$ - LABEL_IDT
IdtPtr		dw	IdtLen - 1	; 段界限
		dd	0		; 基地址
; END of [SECTION .idt]

[SECTION .s16]
[BITS	16]
LABEL_BEGIN:
	mov	ax, cs
	mov	ds, ax
	mov	es, ax
	mov	ss, ax
	mov	sp, 0100h
	
	mov	[LABEL_GO_BACK_TO_REAL+3], ax
	mov	[_wSPValueInRealMode], sp
	
	; 初始化 16 位代码段描述符
	mov	ax, cs
	movzx	eax, ax
	shl	eax, 4
	add	eax, LABEL_SEG_CODE16
	mov	word [LABEL_DESC_CODE16 + 2], ax ;ds:LABEL_DESC_CODE16
	shr	eax, 16
	mov	byte [LABEL_DESC_CODE16 + 4], al
	mov	byte [LABEL_DESC_CODE16 + 7], ah

	; 初始化 32 位代码段描述符
	xor	eax, eax
	mov	ax, cs
	shl	eax, 4
	add	eax, LABEL_SEG_CODE32
	mov	word [LABEL_DESC_CODE32 + 2], ax
	shr	eax, 16
	mov	byte [LABEL_DESC_CODE32 + 4], al
	mov	byte [LABEL_DESC_CODE32 + 7], ah

	; 为加载 GDTR 作准备
	xor	eax, eax
	mov	ax, ds
	shl	eax, 4
	add	eax, LABEL_GDT		; eax <- gdt 基地址
	mov	dword [GdtPtr + 2], eax	; [GdtPtr + 2] <- gdt 基地址

	; 为加载 IDTR 作准备
	xor	eax, eax
	mov	ax, ds
	shl	eax, 4
	add	eax, LABEL_IDT		; eax <- idt 基地址
	mov	dword [IdtPtr + 2], eax	; [IdtPtr + 2] <- idt 基地址

	; 保存 IDTR
	sidt	[_SavedIDTR] ;保存IDTR寄存器的值到ds:_SavedIDTR

	; 保存中断屏蔽寄存器(IMREG)值
	in	al, 21h
	mov	[_SavedIMREG], al  

	; 加载 GDTR
	lgdt	[GdtPtr]
	
	; 关中断
	cli ;int 80h可以起作用,但是可屏蔽中断(通过8255设置的)就不能响应了 IF=0
	
	; 加载 IDTR	
	lidt	[IdtPtr]
	

	; 打开地址线A20
	in	al, 92h
	or	al, 00000010b
	out	92h, al

	; 准备切换到保护模式
	mov	eax, cr0
	or	eax, 1
	mov	cr0, eax

	; 真正进入保护模式
	jmp	dword SelectorCode32:0	; 执行这一句会把 SelectorCode32 装入 cs,
					; 并跳转到 Code32Selector:0  处
					
LABEL_REAL_ENTRY:		; 从保护模式跳回到实模式就到了这里
	mov	ax, cs
	mov	ds, ax
	mov	es, ax
	mov	ss, ax
	mov	sp, [_wSPValueInRealMode]

	lidt	[_SavedIDTR]	; 恢复 IDTR 的原值

	mov	al, [_SavedIMREG]	; ┓恢复中断屏蔽寄存器(IMREG)的原值
	out	21h, al			; ┛

	in	al, 92h		; ┓
	and	al, 11111101b	; ┣ 关闭 A20 地址线
	out	92h, al		; ┛

	sti			; 开中断

	mov	ax, 4c00h	; ┓
	int	21h		; ┛回到 DOS
; END of [SECTION .s16]


[SECTION .s32]; 32 位代码段. 由实模式跳入.
[BITS	32]

LABEL_SEG_CODE32:
	mov	ax, SelectorVideo
	mov	gs, ax			; 视频段选择子(目的)

	call	Init8259A

	int	080h ;内中断,类似调用门
	sti ;开中断后,时钟中断开始生效 IF=1
	jmp	$ ;为了演示结果,去掉后跳回实模式
	
	call	SetRealmode8259A


	; 到此停止
	jmp	SelectorCode16:0
	
; Init8259A ---------------------------------------------------------
Init8259A:
	mov	al, 011hn ;00010001
	out	020h, al	; 主8259, ICW1.
	call	io_delay

	out	0A0h, al	; 从8259, ICW1.
	call	io_delay

	mov	al, 020h	; IRQ0 对应中断向量 0x20 00100000   因为前0-19号中断已经被占了
	out	021h, al	; 主8259, ICW2.
	call	io_delay

	mov	al, 028h	; IRQ8 对应中断向量 0x28 00101000
	out	0A1h, al	; 从8259, ICW2.
	call	io_delay

	mov	al, 004h	; IR2 对应从8259 00000100
	out	021h, al	; 主8259, ICW3.
	call	io_delay

	mov	al, 002h	; 对应主8259的 IR2 0000 0010
	out	0A1h, al	; 从8259, ICW3.
	call	io_delay

	mov	al, 001h 0000 0001
	out	021h, al	; 主8259, ICW4.
	call	io_delay

	out	0A1h, al	; 从8259, ICW4.
	call	io_delay

	;mov	al, 11111111b	; 屏蔽主8259所有中断
	mov	al, 11111110b	; 仅仅开启定时器中断,外部可屏蔽中断只有在IF=1和IMR对应位为0时才响应
	out	021h, al	; 主8259, OCW1.
	call	io_delay

	mov	al, 11111111b	; 屏蔽从8259所有中断
	out	0A1h, al	; 从8259, OCW1.
	call	io_delay

	ret
; Init8259A ---------------------------------------------------------


; SetRealmode8259A ---------------------------------------------------------
SetRealmode8259A:

	mov	al, 017h 0001 0111
	out	020h, al	; 主8259, ICW1.
	call	io_delay ;4个字节中断向量,单个8259

	mov	al, 008h	; IRQ0 对应中断向量 0x8
	out	021h, al	; 主8259, ICW2.
	call	io_delay ;ICW3已经不需要了

	mov	al, 001h
	out	021h, al	; 主8259, ICW4.
	call	io_delay



	ret
; SetRealmode8259A ---------------------------------------------------------

io_delay:
	nop
	nop
	nop
	nop
	ret

; int handler ---------------------------
_ClockHandler:
ClockHandler	equ	_ClockHandler - $$
	inc	byte [gs:((80 * 0 + 70) * 2)]	; 屏幕第 0 行, 第 70 列。
	mov	al, 20h
	out	20h, al				; 发送 EOI
	iretd  ;IRETD 指令先弹出一个32位的EIP值,然后再弹出一个32位值并将最低的2个字节值传入CS寄存器,
	       ;最后再弹出一个32位的标志寄存器值

_UserIntHandler:
UserIntHandler	equ	_UserIntHandler - $$
	mov	ah, 0Ch				; 0000: 黑底    1100: 红字
	mov	al, 'I'
	mov	[gs:((80 * 0 + 70) * 2)], ax	; 屏幕第 0 行, 第 70 列。
	iretd

_SpuriousHandler:
SpuriousHandler	equ	_SpuriousHandler - $$
	mov	ah, 0Ch				; 0000: 黑底    1100: 红字
	mov	al, '!'
	mov	[gs:((80 * 0 + 75) * 2)], ax	; 屏幕第 0 行, 第 75 列。
	jmp	$
	iretd
; ---------------------------------------

SegCode32Len	equ	$ - LABEL_SEG_CODE32
; END of [SECTION .s32]

; 16 位代码段. 由 32 位代码段跳入, 跳出后到实模式
[SECTION .s16code]
ALIGN	32
[BITS	16]
LABEL_SEG_CODE16:
	; 跳回实模式:
	mov	ax, SelectorNormal
	mov	ds, ax
	mov	es, ax
	mov	fs, ax
	mov	gs, ax
	mov	ss, ax

	mov	eax, cr0
	and	al, 11111110b
	mov	cr0, eax

LABEL_GO_BACK_TO_REAL:
	jmp	0:LABEL_REAL_ENTRY	; 段地址会在程序开始处被设置成正确的值

Code16Len	equ	$ - LABEL_SEG_CODE16

; END of [SECTION .s16code]


    
[3] delegate为何用弱引用
    来源: 互联网  发布时间: 2014-02-18
delegate为什么用弱引用

比如在A页面设置B的delegate为A的实例, 

// A.m中某处

B* b = [B alloc] init];

b.delegate = self;

[self.view addSubview:b];

[b release];

那么

1.是A负责创建B的,A的生命周期一定比B要长(B存在,A一定也存在;A存在,B不一定存在)

也就是说 在B(实例b)存在的时候,A(的实例)一定存在, 所以没有必要用retain将引用计数+1,assign足以

 

2.退一步假设存在这样的情况:A比B先挂掉(A的实例先被release销毁)

那么当然希望是[a relase]后,A中的方法不再被B调用,但是使用retain时候,A还是没有被销毁,所以 A中的方法仍会被B调用,但是assgin就无此问题

 

3.本质上delegate就是一根指向先于它存在的某个类(CCClass)的指针(假设是:ccPoint),我们通过delegate这根指针去指向这个已经存在的指针(ccPoint) 那么通过delegate即ccPoint也就可以访问CCClass中的实例方法


4.避免retain cycle,即:有A,B两个Object, A中有一个B的实例变量,B中又有一个A的实例变量,要release A就必须releaseA中的B,而要release B有必须release B中的A,这样就产生了一个Retain Circle,A B都不能被dealloc.解决Retain Circle的方法就是使用弱引用(weak reference),弱引用没有被引用的那个Object的所有权,也就不需要release它,从而解决了Retain Circle问题.为了防止Retain Circle的发生, delegate通常都是弱引用的, 因此我们一般不应该retain一个delegate。NSURLConnection是个例外。

    
最新技术文章:
▪Android开发之登录验证实例教程
▪Android开发之注册登录方法示例
▪Android获取手机SIM卡运营商信息的方法
▪Android实现将已发送的短信写入短信数据库的...
▪Android发送短信功能代码
▪Android根据电话号码获得联系人头像实例代码
▪Android中GPS定位的用法实例
▪Android实现退出时关闭所有Activity的方法
▪Android实现文件的分割和组装
▪Android录音应用实例教程
▪Android双击返回键退出程序的实现方法
▪Android实现侦听电池状态显示、电量及充电动...
▪Android获取当前已连接的wifi信号强度的方法
▪Android实现动态显示或隐藏密码输入框的内容
▪根据USER-AGENT判断手机类型并跳转到相应的app...
▪Android Touch事件分发过程详解
▪Android中实现为TextView添加多个可点击的文本
▪Android程序设计之AIDL实例详解
▪Android显式启动与隐式启动Activity的区别介绍
▪Android按钮单击事件的四种常用写法总结
▪Android消息处理机制Looper和Handler详解
▪Android实现Back功能代码片段总结
▪Android实用的代码片段 常用代码总结
▪Android实现弹出键盘的方法
▪Android中通过view方式获取当前Activity的屏幕截...
▪Android提高之自定义Menu(TabMenu)实现方法
▪Android提高之多方向抽屉实现方法
▪Android提高之MediaPlayer播放网络音频的实现方法...
▪Android提高之MediaPlayer播放网络视频的实现方法...
▪Android提高之手游转电视游戏的模拟操控
 


站内导航:


特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

©2012-2021,,E-mail:www_#163.com(请将#改为@)

浙ICP备11055608号-3