汇编代码和开关声明案例

时间:2015-10-19 05:41:31

标签: c assembly switch-statement jump-table

我在理解如何通过汇编语言确定案例50,52等方面遇到了一些麻烦。

根据我的理解,跳转表对应于每种情况下要执行的操作以及检查edx> 5意味着案件范围从0到5?我认为1是遗漏的,因为它是默认情况,但为什么还有5个被遗漏?

我觉得应该有一个案例55:结果* =结果,没有?

如果有人能帮忙解释,那就太好了。谢谢!

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

图3.38显示了该过程的反汇编对象代码。我们只是       对第4到16行显示的代码部分感兴趣。我们可以在第4行看到       参数x(相对于%ebp的偏移量8)被加载到寄存器%eax中,对应于       程序变量结果。第11行的“lea 0x0(%esi),%esi”指令是一个nop       插入的指令使第12行的指令从a的地址开始       16的倍数

     

跳转表位于不同的内存区域。使用调试器GDB,       我们可以检查从地址0x8048468开始的六个4字节内存字       命令x / 6w 0x8048468。 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
     

汇编代码:

$ gem uninstall rake
Successfully uninstalled rake-10.4.2
$ gem install rake
Fetching: rake-10.4.2.gem (100%)
Successfully installed rake-10.4.2
Parsing documentation for rake-10.4.2
Installing ri documentation for rake-10.4.2
Done installing documentation for rake after 1 seconds
1 gem installed
$rake

1 个答案:

答案 0 :(得分: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;
}

这可能是由于人为错误造成的(例如更新问题中的源代码,因此它与去年学生得到的问题不一样,但忘记更新程序集以匹配)。

永远不要认为教师/教授是非人类......