开关盒组装语言

时间:2010-10-24 13:59:20

标签: assembly x86 switch-statement disassembly

我正在查看switch语句的汇编语言代码。

我理解代码是如何工作的以及案例是什么。我的问题是我如何决定案件名称?

下面是汇编语言代码,我将对其进行解释。我基本上只需要使用跳转表并填写案例名称。

    1 8048420: push %ebp
    2 8048421: mov %esp, $ebp
    3 8048423: mov 0x8(%ebp), %eax       // x
    4 8048426: mov 0xc(%ebp), %edx       // n
    5 8048429: sub $0x32, %edx           // so least value of case is 32
    6 804842c: cmp $0x5, %edx            // max value is 37
    7 804842f: ja 8048448 <switch+0x28>  // if >37, go to default
    8 8048431: jmp *0x80485d0(, %edx, 4)  //THIS RIGHT HERE ?
    9 8048438: shl $0x2, %eax             // CASE A
   10 804843b: jmp 804844b <switch+0x2b>  //break;
   11 804843d: sar $0x2, %eax             //CASE B
   12 8048440: jmp 804844b <switch+0x2b>  //break
   13 8048442: lea (%eax, %eax, 2), %eax  //CASE C
   14 8048445: imul %eax, %eax     
   15 8048448: add $0xa, %eax             //fall through to default
   16 804844b: pop %ebp                   //return
   17 804844c: ret

gdb命令创建的跳转表: 我正在做x / 6w 0x80485d0

0x80485d0: 0x08048438 0x08048448 0x08048438 0x0804843d
0x80485e0: 0x08048442 0x08048445

我的解释:

int result = x;
switch(n) {
case __:
    x = x << 2;
    break;  
case __:
    x = x >> 2
    break;
case __:
    x = 4*x;
    x = x*x
case __: //default
    x += 0xa 
return x;
}

我只是不明白如何查找跳转表并确定32到37之间的n值适合哪种情况下的空白。

任何帮助将不胜感激。 谢谢。

2 个答案:

答案 0 :(得分:5)

正如奥利所说,没有更多的事要做。 n-50存储在%edx中,然后切换+ 0x11跳转到存储在0x80485d0 + %edx * 4中的地址。看一下表,当n == 50或52时,开关+ 0x18,当n == 51时切换+ 0x28,当n == 53时切换+ 0x1d,当n == 54时切换+ 0x22,当n =时切换+ 0x25 = 55

答案 1 :(得分:1)

跳转表有6个值,其中5个是不同的(因此,有5种情况,包括默认值0x8048448)。第一个和第三个(对应于0x32和0x34)转到第一种情况,第二种(0x33)转到最后(第五种)情况,第四种(0x35)转换到第二种情况,第五种(0x36)转到第三种情况,第六个(0x37)到第四个案例。其他所有内容都转到最后一个(第五个),使其成为默认值。

switch (n)
{
  case 0x32:
  case 0x34:
    x <<= 2;
    break;
  case 0x35:
    x >>= 2;
    break;
  case 0x36:
    x *= 3;
  case 0x37:
    x *= x;
  //case 0x33:  // not really necessary
  default:
    x += 10;
}
return x;