【问题标题】:Assembly Code and Switch Statement Cases汇编代码和 Switch 语句案例
【发布时间】:2016-01-17 09:10:37
【问题描述】:

我有点难以理解案例 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)被加载到寄存器 %eax,对应于 程序变量结果。第 11 行的“lea 0x0(%esi), %esi”指令是 nop 插入的指令以使第 12 行的指令从一个地址开始 16的倍数

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

【问题讨论】:

  • 嗯,你确实有五个开关在。
  • 我不应该有 6,因为案例 5 对应于 0x80483e8? @JoachimPileborg
  • 从零开始计数,从05(含)共有六个数字。 :)
  • @JoachimPileborg。是的,但在我的示例中,默认情况下只有 50、52、53、54 和 51。少了55?还是被 54 吸收了
  • 您可能知道lea 0xffffffce(%eax),%edx 有效地将-50(十进制)添加到eax(变量x)并将其存储在edx(edx=-50+x)中。

标签: c assembly switch-statement jump-table


【解决方案1】:

程序集与源代码不匹配。它匹配更像这样的东西:

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;
}

这很可能是人为错误造成的(例如更新问题中的源代码,使其与去年学生得到的问题不完全相同,但忘记更新程序集以匹配)。

永远不要假设教师/教授不是人类......

【讨论】:

  • 我同意人为错误,听起来提供的答案不正确(答案可能基于上学期的类似练习,并且没有正确更新)
  • 谢谢!这更有意义。问题也来自哈佛的作业 Lol
  • @Crowning:您加入会员已有一段时间了,您的各种问题得到了一些很好的答案。您现在可能想接受其中的几个:What should I do when someone answers my question?。也许您也应该阅读介绍性的tour。 (不用担心 - 它很短!它很友好!它信息丰富!它会在你的个人资料中为你赢得一个徽章!)
猜你喜欢
  • 1970-01-01
  • 2013-01-14
  • 2010-10-23
  • 2014-01-03
  • 1970-01-01
  • 2011-01-19
  • 1970-01-01
  • 2021-03-22
  • 2015-06-21
相关资源
最近更新 更多