2012-03-01 3 views
0

私はarch/mips/lib/csum_partial.Sにあるcsum_partial()関数コードをバニラカーネル2.6.35で理解しようとしています。入力の長さが8バイト未満の場合、バグがあるようです。私は、関数が入力の長さが8未満である場合にはMIPS csum_partial

/* 
* a0: source address 
* a1: length of the area to checksum 
* a2: partial checksum 
*/ 

#define src a0 

#define sum v0 

    .text 
    .set noreorder 
    .align 5 
LEAF(csum_partial) 
    move sum, zero 
    move t7, zero 

    sltiu t8, a1, 0x8 
    bnez t8, .Lsmall_csumcpy  /* < 8 bytes to copy */ 
    move t2, a1 

を次のように開始し、我々はsmall_csumcpyにジャンプし、到達していないここ を求めている理由です、それは合理的で鳴らないことを知っていますmoveコマンド、そう?そしてそこに私たちがあります:

.Lsmall_csumcpy: 

    move a1, t2 
    ... 

私の質問はどこにt2レジスタが初期化されたのですか? ありがとうございます!次のコードで

答えて

1

moveのでt2.Lsmall_csumcpy:に正しい値を有し、分岐が実行される前にt2レジスタが割り当てられますBranch Delay Slot

bnez t8, .Lsmall_csumcpy  /* < 8 bytes to copy */ 
move t2, a1 

です。 move命令は、遅延スロット内にあることを読者に示すためにコードにインデントされています。

アセンブラは、通常NOP Sと遅延スロットを埋めるが、原因.set noreorderディレクティブに、アセンブラは、彼らが中に書かれていることを正確な順序でこのコードの指示に組み立てる。教室で使用されている一部のMIPSのシミュレータが行う

デフォルトでは分岐遅延スロットを有効にしないため、遅延スロットが有効になっていない限り、このコードはこのようなシミュレータでは正しく動作しない可能性があります。

+0

ちょっとした注意:QtSpim/Spim/Marsのようなシミュレータのほとんどは遅延分岐オプションを持っていますが、通常は無効になっています。設定/オプションダイアログから手動で有効にする必要があります。 – Wiz

+0

ありがとう!私は私の答えを編集しました。 – markgz

+0

うわー、ありがとう!私はブランチ後の命令は、インデントと一般的なロジックのために何らかの形で実行されていると思っていますが、私が尋ねたすべての人は、これは起こり得ないと私に言った。再度、感謝します! – alexa