2015-02-06 5 views
0

В функции switch_case, у меня возникают проблемы, глядя на него, когда он реализует таблицу переходов против проще L1 :, L2 :, L3: и т.д.Сборка x86 включение случай путаницы

 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; 

    } 

Я знаю один случай х + = 2; другой - х = 2; другой может быть x < < 3; x ++; , но я полностью потерял, узнав, куда они идут, и что такое сравнение.

+0

И вопрос в том, что? –

+0

Я не уверен, что понимаю, что вы подразумеваете под «Я не вижу смещения в адресе инструкции» - строка, помеченная вопросительными знаками, перескакивает на 0x8048420 - инструкция, хорошо видимая в вашем фрагменте. –

+0

Непонятно, почему я пропустил это – SSOPLIF

ответ

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 указателя, для 4-х корпусов.

Смежные вопросы