2015-02-06 54 views
0

在功能switch_case,碰到問題看它時,它實現了一個跳轉表VS越容易L1 :, L2:,L3:等大會86的switch-case混亂

 080483ec <switch_case>:  
    80483ec:   push %ebp 
    80483ed:   mov %esp,%ebp 
    80483ef:   sub $0x10,%esp //create stack space 
    80483f2:   mov 0x8(%ebp),%eax //param x 
    80483f5:   mov %eax,-0x4(%ebp) //x moved into -0x4(%ebp) 
    80483f8:   mov 0xc(%ebp),%eax //param n moved into %eax 
    80483fb:   sub $0x21,%eax //subtract 21 from n 
    80483fe:   cmp $0x4,%eax //compare 4 with n 
    8048401:   ja  8048420 <switch_case+0x34> // jumping to 804820 
    8048403:   mov 0x80484e0(,%eax,4),%eax 
    804840a:   jmp *%eax 
    804840c:   subl $0x2,-0x4(%ebp) 
    8048410:   jmp 8048427 <switch_case+0x3b> 
    8048412:   addl $0x2,-0x4(%ebp) 
    8048416:   jmp 8048427 <switch_case+0x3b> 
    8048418:   shll $0x3,-0x4(%ebp) 
    804841c:   addl $0x1,-0x4(%ebp) 
    8048420:   movl $0xa,-0x4(%ebp) // default starts here x=10 
    8048427:   mov -0x4(%ebp),%eax // n=x 
    804842a:   leave 
    804842b:   ret 

我的問題是:

我怎麼知道哪些指令這種情況下嗎?

到目前爲止我理解(翻譯成C):

int switch_case(int x, int n) 
    { 

    int result = x; 

    switch(n) { 

    case(): 
     x-=21; //guessing. dont think so? 
      break; 
    case(): 

      break; 
    case(): 

      break; 
    case(): 

      break; 

    default: 
    x=10; 
n=x; 

      break; 

      }//end 

    return result; 

    } 

我知道一種情況下爲x + = 2;另一個是x- = 2;另一個可能是x < < 3; x ++; ,但我完全迷失在找出他們去哪裏以及比較的是什麼

+0

問題是? – 2015-02-06 20:59:41

+0

我不知道我明白你的意思是'我沒有看到偏移的instruction'的地址 - 行打上問號跳轉到0x8048420 - 一個指令程式碼中清晰可見。 – 2015-02-06 21:00:41

+0

固定 - 不知道爲什麼我錯過了 – SSOPLIF 2015-02-06 21:13:14

回答

0

subtract 21是以十六進制開頭的,所以這就是subtract 33十進制。另外它在使用跳轉表之前發生。的邏輯是:

unsigned tmp = n - 33; 
if (tmp > 4) goto default; 
goto table[tmp]; 

這意味着,tmp可以是0 .. 3包容這又意味着用於n範圍是33 .. 36。至於代碼的位置,您需要查看跳轉表。從地址0x80484e0開始,您將獲得4個指針。