0

ねえ、次のスイッチ ステートメントのコンパイラによって省略されたアセンブリ コードを理解するのに問題があります。gcc などを使って見る通常のアセンブリ コードとは異なります。

switch(instr) { 
case OP_NOP: 
    break;

case OP_BIPUSH: 
    stack_push(arg0.z.bh); pc_inc = 2; break;
} 

上記の C コードのアセンブリ コード:

switch(instr){ 
+00001482: 8529 LDD R18,Y+9 Load indirect with displacement 
+00001483: 2F82 MOV R24,R18 Copy register 
+00001484: E090 LDI R25,0x00 Load immediate 
+00001485: 01FC MOVW R30,R24 Copy register pair 
+00001486: 9732 SBIW R30,0x02 Subtract immediate from word 
+00001487: 3BED CPI R30,0xBD Compare with immediate 
+00001488: 05F1 CPC R31,R1 Compare with carry 
+00001489: F008 BRCS PC+0x02 Branch if carry set 
+0000148A: C39D RJMP PC+0x039E Relative jump 
+0000148B: 57E0 SUBI R30,0x70 Subtract immediate 
+0000148C: 4FFF SBCI R31,0xFF Subtract immediate with carry 
+0000148D: 0FEE LSL R30 Logical Shift Left 
+0000148E: 1FFF ROL R31 Rotate Left Through Carry 
+0000148F: 9005 LPM R0,Z+ Load program memory and postincrement 
+00001490: 91F4 LPM R31,Z Load program memory 
+00001491: 2DE0 MOV R30,R0 Copy register 
+00001492: 9409 IJMP Indirect jump to (Z) 
2003: stack_push(arg0.z.bh); pc_inc = 2; 
+00001493: 2D85 MOV R24,R5 Copy register 
+00001494: 2799 CLR R25 Clear Register 
+00001495: FD87 SBRC R24,7 Skip if bit in register cleared 
+00001496: 9590 LAT R25 Load and Toggle 
+00001497: C338 RJMP PC+0x0339 Relative jump 

場合のコードを推測します: NOP はコンパイラによって最適化されています。

しかし、コードがケースのルックアップテーブルをどのように設定しているかを理解していますか??

どんな助けでも素晴らしいでしょう、ありがとう。

4

1 に答える 1

2

あなたの例でチェックするケースは 1 つしかないため、instrが と等しいかどうかをチェックするだけOP_BIPUSHです。その場合はスキップして残りを実行し、そうでない場合は関数呼び出しから戻ります。

呼び出しの開始時に、Y レジスタ (これは実際には 2 つの汎用レジスタです。どれかは忘れました) がスタックの一番上を指しています。パラメータinstrはスタックの 9 スポット下にあり、r24 にロードされます。r25 は 0 になるため、ペアには の値が含まれますinstr

テストする必要があるのは 1 つのことだけなので、2 を引いて と比較し0xBDます。(r1 はゼロレジスタです。常に 0 が含まれます。)

結果が等しい場合は、次の命令をスキップして残りの命令を続行します。それらが等しくない場合は、関数呼び出しからジャンプして戻る次の命令を実行します。

于 2013-01-31T00:32:18.273 に答える