1

50、52 などのケースがアセンブリ言語でどのように決定されたかを理解するのに少し苦労しています。

私が理解していることから、ジャンプ テーブルは各ケースで実行するアクションに対応し、edx > 5 のチェックはケースが 0 から 5 の範囲であることを意味しますか? 1 はデフォルトのケースなので省略されていると思いますが、5 が省略されているのはなぜですか?

ケース 55 があるべきだと思います: where result *= result, no?

誰かが説明を手伝ってくれるなら、それは素晴らしいことです。ありがとうございました!

int switch_prob(int x) 
{
    int result = x;
    switch (x)
    {
        case 50:
        case 52:
            result <<= 2;
            break;
        case 53:
            result >>= 2;
            break;
        case 54:
            result *= 3;
            break;
        default:
            result += 10;   
    }
    return result;
}

図 3.38 に、逆アセンブルされたプロシージャのオブジェクト コードを示します。4 行目から 16 行目に示されているコードの部分のみに注目します。4 行目で、パラメーター x (%ebp に対するオフセット 8) がプログラム変数 result に対応するレジスター %eax にロードされていることがわかります。11 行目の「lea 0x0(%esi), %esi」命令は、12 行目の命令を 16 の倍数のアドレスから開始させるために挿入された nop 命令です。

ジャンプ テーブルは、メモリの別の領域にあります。デバッガー GDB を使用して、コマンド x/6w 0x8048468 を使用して、アドレス 0x8048468 で始まるメモリの 6 つの 4 バイト ワードを調べることができます。GDB は以下を出力します。

(gdb) x/6w
0x8048468: 0x080483d5 0x080483eb 0x080483d5 0x0x80483e0
0x8048478: 0x080483e5 0x080483e8
(gdb)

アセンブリ コード:

1: 080483c0 <switch_prob>:
2: 80483c0: push %ebp
3: 80483c1: mov %esp,%ebp
4: 80483c3: mov 0x8(%ebp),%eax // X is copied into eax ; eax = x
5: 80483c6: lea 0xffffffce(%eax),%edx // placeholder 
6: 80483c9: cmp $0x5, %edx // Compare edx (3rd argument) with 5; Edx - 5 // clearly, edx is x
7: 80483cc: ja 80483eb <switch_prob+0x2b> // if edx - 5 > 0, Jump into line 16 (default)
8: 80483ce: jmp *0x8048468(,%edx,4) // Go into the jump table
9: 80483d5: shl $0x2, %eax // eax << 2
10: 80483d8: jmp 80483ee <switch_prob+0x2e> // Jump to line 17
11: 80483da: lea 0x0(%esi),%esi // esi = esi  NOP. Filling in N bytes
12: 80483e0: sar $0x2, %eax // eax >> 2
13: 80483e3: jmp 80483ee <switch_prob+0x2e> // Jump to line 17
14: 80483e5: lea (%eax, %eax, 2), %eax // eax = eax + 2(eax)
15: 80483e8: imul %eax, %eax // eax *= eax
16: 80483eb: add $0xa, %eax // eax += 10
17: 80483ee: mov %ebp, %esp // esp = ebp
18: 80483f0: pop %ebp
19: 80483f1: ret
4

1 に答える 1

4

アセンブリがソース コードと一致しません。次のようなものに一致します。

int switch_prob(int x) 
{
    int result = x;
    switch (x)
    {
        case 50:
        case 52:
            result <<= 2;
            break;
        case 53:
            result >>= 2;
            break;
        case 54:
            result *= 3;
            // WARNING: Falls through
        case 55:
            result *= result;
            // WARNING: Falls through
        default:
            result += 10;   
            break;
    }
    return result;
}

これはおそらく人為的ミスによるものです (たとえば、問題のソース コードを更新して、昨年の学生が受け取った問題と同じではなく、アセンブリを更新して一致させるのを忘れたなど)。

教師や教授が人間ではないと思い込まないでください...

于 2015-10-19T07:07:39.217 に答える