さくらびと-SunSet Swish

喜びが舞う春を思う 涙の羽
散り行くは 涙となりあなたの元へと
风が鸣るたび 傍にいるよ
辿り着ける 悲しみより 寂しさより
守るべきは今を生きるあなた
生まれ変わったら桜の下でまた会いましょう
きっとその时には笑って 永远を誓おう
爱し爱されてこの命は 芽吹いて咲いて
色褪せない眼差しを胸に 舞い散る愿い
呜呼、あなたに…
ただ会いたい
降り注ぐ雨音 止むまで光は无く
右と左の翼は 伤付き揺れてる
穏やかな日々 信じながら
爱してると 伝えたくて 伝えないのは
忘れて欲しい 明日を生きるために
生まれ変わったら桜の下でまた会いましょう
待ち焦がれた季节の中で 共に歩こう
この心を染め抜いた花よ
あなたに届け
夸り高き远い空で 名も无き风に
大切なものはいつの时代も
変わらないことを
人は知りながら 过ちを何故缲り返す?
生まれ変わったら桜の下でまた会いましょう
きっとその时には笑って 永远を誓おう
爱し爱されてこの命は 芽吹いて咲いて
色褪せない眼差しを胸に 舞い散る愿い
呜呼、あなたに…
ただ会いたい

Simple Implementation of Big Integer Multiply

public static int[] BigIntegerMultiply(int[] op1, int[] op2)
{
    int[][] _immediate = new int[op2.Length][];

    for (int j = 0; j < op2.Length; j++)
    {
        int[] _temp = new int[op1.Length];
        for (int i = 0; i < op1.Length; i++)
            _temp[i] = op2[j] * op1[i];
        _immediate[j] = _temp;
    }

    int[] result0 = new int[op1.Length + op2.Length – 1];

    for (int i = 0; i < result0.Length; i++)
    {
        int index0 = i;
        for (int j = 0; j < _immediate.Length; j++)
        {
            if (index0 < 0)
                break;
            if (index0 >= _immediate[j].Length)
            {
                index0–;
                continue;
            }
            result0[i] += _immediate[j][index0];
            index0–;
        }
    }

    int head = 0;
    for (int i = result0.Length – 1; i >= 0; i–)
    {
        if (result0[i] > 9)
        {
            // may have carry…
            if (i – 1 < 0)
                head = result0[i] / 10;
            else
                result0[i – 1] += result0[i] / 10;

            result0[i] = result0[i] % 10;
        }
    }

    int[] result1 = new int[head == 0 ? result0.Length : result0.Length + 1];

    int index1 = 0;
    if (head != 0)
    {
        result1[0] = head;
        index1 = 1;
    }
    Array.Copy(result0, 0, result1, index1, result0.Length);

    return result1;
}

注释GetFATEntry

花了将近两天的时间,反复比对书上的概念和网上前辈们的总结,总算把这段代码给搞清楚了。(这里使用的是FAT12软盘结构)

函数GetFATEntry。参数存放在ax寄存器中,表示一个簇号。输出结果是该簇号在FAT表中的FATENTRY,它的内容仍然是一个簇号,表示文件下一部分所在簇的簇号。这里要仔细地体会“簇号”和“簇”之间的差别,否则在看代码的时候,很容易就会迷失。“簇”表示一个或多个扇区的集合。FAT12中,一个簇就是一个扇区,512字节。簇号,从软盘的数据区开始,从2开始编号(0,1为系统使用),本质上是一个基于FAT表的索引。

GetFATEntry:
    push    es
    push    bx

;函数中使用到了es和bx所以要进行保存,保存在栈上。

;es:bx会被函数ReadSector所使用,是int 13h所要求的,指向了一个缓冲区,保存从软盘读进来的数据。
    push    ax
    mov    ax, BaseOfLoader
    sub    ax, 0100h   

;以上在BaseOfLoader之后留出4KB空间。为什么明明是0100h(256),怎么说是4K?

;因为这是个段基址,0100h还要乘上个16。
    mov    es, ax       
    pop    ax
    mov    byte [bOdd], 0
    mov    bx, 3
    mul    bx
    mov    bx, 2
    div    bx   
    cmp    dx, 0
    jz    LABEL_EVEN
    mov    byte [bOdd], 1

;以上部分是整个函数的难点所在,用户计算簇号在FAT表中所对应的FATENTRY相对于FAT首地址的偏移。

;从书上可以得知,FAT12中每个FATENTRY是12位的。所以如下:

7654 | 3210(byte1)    7654|3210(byte2)    7654|3210(byte3)

byte1和byte2的低4位表示一个Entry;根据Big-Endian,Entry内容为:3210(byte2)76543210(byte1)

byte3和byte2的高4位表示一个Entry;根据Big-Endian,Entry内容为:76543210(byte3)7654(byte2)

所以这里存在一个奇偶数的问题,以字节为单位。以上为例,Entry0偏移为0,Entry1偏移为1,Entry2偏移为3。

以INT[“簇号”*1.5]的方式增加。这也就是为什么上面先乘3再除2来计算。

根据DIV指令规定,商保存在ax中,余数在dx中。所以此时ax就是FATENTRY在FAT中以字节为边界的偏移量。

——————————————————————————————–
LABEL_EVEN:
    xor    dx, dx   
    mov    bx, [BPB_BytsPerSec]
    div    bx   

;dx:ax/BPB_BytsPerSec,所以ax现在是扇区的个数,dx是在最后一个扇区中的偏移。
    push    dx
    mov    bx, 0   

;es:bx指向了目标空间的首地址,就是函数开始在BaseOfLoader之后留出的4KB空间。
    add    ax, SectorNoOfFAT1   

;SectorNoOfFAT1是FAT1的相对扇区号,物理上就是0面0道1扇区。FAT12有两个完全一样的FAT表,FAT1和FAT2。
    mov    cl, 2

;cl总保存ReadSector函数的参数,表示要连续读入2个扇区。另一个参数ax在前面已经给出。
    call    ReadSector   
    pop    dx
    add    bx, dx

;在add之前,bx为目标空间的首地址,其中内容是包含FATEntry的扇区。bx+dx就定位到了该FATEntry。
    mov    ax, [es:bx]

;ax中为es:bx指向的空间的内容。
    cmp    byte [bOdd], 1

;是奇数的簇号还是偶数的簇号??
    jnz    LABEL_EVEN_2
    shr    ax, 4

;7654 | 3210(byte1)    7654|3210(byte2)    7654|3210(byte3)

根据上面这个例子,奇数的簇号,1,偏移为1,所以读要ax中的时候,因为ax是16位,所以根据Big-Endian,ax的内容为7654|3210(byte3)|7654|3210(byte2),所以右移4位就可以了。

偶数簇号,0,偏移为0,读入ax后,ax的内容为7654|3210(byte2)7654 | 3210(byte1),我们只需要低12位即可,

所以and ax,0FFFh。

——————————————————————————————–
LABEL_EVEN_2:
    and    ax, 0FFFh

LABEL_GET_FAT_ENRY_OK:

    pop    bx
    pop    es
    ret

Win Autobucks with Stephen

^_________^
 
Hi All,
 
I want to thank Austin and Stephen for their good works on our CIP Client project and CER project.
 
Austin Dai did very good work on CER Mac client and backend projects. He joined the CER Mac project at the critical time and got familiar with the design and code very quick. Closely work with Seema and other US team members, he helped us successfully deliver the CER Mac client and backend. Also, he provided support for the product teams and resolved bunch of defects reported.
 
Stephen Song made the important contribution on our CIP Client. Co-work with Chris and other US team members, he completed the tech. spec document. Also, he took a big part of implementation works for our new CIP Client. He resolved many complex issues and helped us successfully delivered the CIP Client 4.0 in time. 
 
Congratulations: they got the Autobucks for their good works!
 
Thanks,   
-Joe