zoukankan      html  css  js  c++  java
  • Delphi + Asm

    技术交流,DH讲解.

    在D2010的classes中有个TBits类,这个类主要是位操作的.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    TBits = class
    private
      FSize: Integer;
      FBits: Pointer;
      procedure Error;
      procedure SetSize(Value: Integer);
      procedure SetBit(Index: Integer; Value: Boolean);
      function GetBit(Index: Integer): Boolean;
    public
      destructor Destroy; override;
      function OpenBit: Integer;
      property Bits[Index: Integer]: Boolean read GetBit write SetBit; default;
      property Size: Integer read FSize write SetSize;
    end;

    这个类没有什么方法,我们看到了property Bits[Index: Integer]: Boolean read GetBit write SetBit; default;这个属性,就是读取和设置某一位的.
    那我们看看它是怎么实现的?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    //在类中Eax就是Self指针
    procedure TBits.SetBit(Index: Integer; Value: Boolean); assembler;
    asm
            CMP     Index,[EAX].FSize  //如果Indx>=Size then 扩容
            JAE     @@Size
     
    @@1:    MOV     EAX,[EAX].FBits
            OR      Value,Value
            JZ      @@2
            BTS     [EAX],Index  //将Eax中第Index位赋值给CF,然后Eax第index位=1;
            RET
     
    @@2:    BTR     [EAX],Index //将Eax中第Index位赋值给CF,然后Eax第index位=0;
            RET
     
    @@Size: CMP     Index,0   //if index <0 then Error
            JL      TBits.Error
            PUSH    Self      //push [eax]
            PUSH    Index
            PUSH    ECX {Value}
            INC     Index
            CALL    TBits.SetSize
            POP     ECX {Value}
            POP     Index
            POP     Self
            JMP     @@1
    end;
     
    function TBits.GetBit(Index: Integer): Boolean; assembler;
    asm
            CMP     Index,[EAX].FSize
            JAE     TBits.Error
            MOV     EAX,[EAX].FBits
            BT      [EAX],Index   //将eax的第Index位赋值给CF
            SBB     EAX,EAX //eax - (eax + CF)
            AND     EAX,1  //清除Eax中的其他位
    end;

    这里我们发现BTR,BTS,BT,SBB等位操作符.我们之前不是算过99999中有多少个一么?
    当时我们用的方法是移位然后与,那么我们现在换个方法呢?

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    Function _1Bits(ANum: Integer): Integer;
    asm
      xor edx,edx // 位数
      xor ecx,ecx // 1的个数
    @@nLoop:
      cmp edx,32  // 循环32次
      je @@nExit
      bt eax,edx
      jnc @@nNoInc // if CF = 0 then
      inc ecx
    @@nNoInc:
      inc edx
      jmp @@nLoop
    @@nExit:
      mov eax,ecx
    end;

    全部都是直接对位操作的.
    BTR和BTS的作用如上面我注释中写的那样,但是我现在没有其他例子给大家看.TBits类很纯洁,所以可以用到其他版本中去.

    我是DH.

    http://www.cnblogs.com/huangjacky/archive/2010/01/19/1651359.html

  • 相关阅读:
    状态压缩dp未吃透の笔记
    洛谷blog传送门qwq
    线段树学习总结(Do not be the cheater)
    第三届NOI Online普及组线上比赛赛后总结
    第三届NOI Online入门组第三题 手表(watch)题解
    P1162 填涂颜色 题解(勿抄袭)
    4980:拯救行动 题解
    P1433 吃奶酪 题解(勿抄袭)
    Mysql-多表数据记录查询
    java-多线程
  • 原文地址:https://www.cnblogs.com/findumars/p/5185253.html
Copyright © 2011-2022 走看看