2010-10-24 125 views
3

我正在查看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之間的哪個值適合於哪個空白。

任何幫助,將不勝感激。 謝謝。

+0

請注意'0x32'是50,而不是32. – 2010-10-24 14:05:06

+0

我不確定我是否理解這個問題;你已經完成了艱苦的工作!跳轉表的第一個元素對應於「0x32」,第二個對應於「0x33」,依此類推。 – 2010-10-24 14:06:22

+1

「x = 4 * x」不應該是「x = 3 * x」(或者更準確地說,「x = x + 2 * x」)? – outis 2010-10-24 14:51:37

回答

5

正如Oli所說,沒有太多的事情要做。 n-50存儲在%edx中,然後switch + 0x11跳轉到存儲在0x80485d0 + %edx * 4中的地址。查看錶格,當n == 50或52時,開關+ 0x18,當n == 51時開關+ 0x28,當n == 53時開關+ 0x1d,當n == 54時開關+ 0x22,當n = = 55。

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;