Интерпретация таблицы переходов сборки

Я пытаюсь интерпретировать построчно, что делает этот ассемблерный код, но я был очень сбит с толку, когда мне представили эту таблицу переходов, которая находится в ассемблере. Это взято из вопроса 3.63 упражнения учебника, но нет объяснения - поэтому и спрашиваю здесь. Цель состоит в том, чтобы перепроектировать предоставленный листинг сборки и написать код C, который мог бы его сгенерировать (почувствуйте тело оператора switch). Пожалуйста помоги :(

Учебник: Рэндал Э. Брайант, Дэвид Р. О'Халларон - Компьютерные системы. Перспектива программиста [3-е изд.] (2016, Пирсон)

qn 3.63

long switch_prob(long x, long n) { 
    long result = x;  
    switch(n) {  
            /* Fill in code here */  
    }  
    return result;  
}  

Я не уверен, как его «расшифровать» или как узнать, куда он указывает.

0000000000400590 <switch_prob>:  
    400590: 48 83 ee 3c             sub $0x3c,%rsi  
    400594: 48 83 fe 05             cmp $0x5,%rsi  
    400598: 77 29                     ja 4005c3 <switch_prob+0x33>  
    40059a: ff 24 f5 f8 06 40 00     jmpq *0x4006f8(,%rsi,8)  
    4005a1: 48 8d 04 fd 00 00 00     lea 0x0(,%rdi,8),%rax  
    4005a8: 00  
    4005a9: c3                         retq  
    4005aa: 48 89 f8                 mov %rdi,%rax  
    4005ad: 48 c1 f8 03             sar $0x3,%rax  
    4005b1: c3                         retq  
    4005b2: 48 89 f8                 mov %rdi,%rax  
    4005b5: 48 c1 e0 04             shl $0x4,%rax  
    4005b9: 48 29 f8                 sub %rdi,%rax  
    4005bc: 48 89 c7                 mov %rax,%rdi  
    4005bf: 48 0f af ff             imul %rdi,%rdi  
    4005c3: 48 8d 47 4b             lea 0x4b(%rdi),%rax  
    4005c7: c3                         retq  

Таблица переходов находится в другой области памяти. Из косвенного перехода в строке 5 видно, что таблица переходов начинается с адреса 0x4006f8. Используя отладчик GDB, мы можем проверить шесть 8-байтовых слов памяти, составляющих таблицу переходов, с помощью команды x/6gx 0x4006f8. GDB выводит следующее:

(GDB) x /6gx 0x4006f8
0x4006f8: 0x000000004005A1 0x00000000004005C3
0x400708: 0x00000000004005A1 0x000000004005AA
0x000000004005A1 0x000000004005AA

Я понимаю, что эта строка 40059a: ff 24 f5 f8 06 40 00 jmpq *0x4006f8(,%rsi,8)
переходит к таблице, но я не знаю, как
1)интерпретировать таблицу переходов [чему соответствует каждый адрес, что означает/удерживает каждое из 6 значений
]
2) провести реинжиниринг, чтобы получить разные варианты оператора switch.

Любая помощь приветствуется, спасибо :)


person Megan Darcy    schedule 27.05.2021    source источник
comment
У вас есть пустой коммутатор, поэтому он вообще не должен генерировать таблицу переходов. Поэтому, пожалуйста, либо обновите свой вопрос, либо предоставьте код, который вы фактически используете.   -  person th33lf    schedule 27.05.2021
comment
@ th33lf смысл в том, чтобы заполнить (обратно инжиниринг) пустой блок переключателей.   -  person Jester    schedule 27.05.2021
comment
Код в основном goto table[rsi-0x3c]. Тебе этого намека достаточно?   -  person Jester    schedule 27.05.2021
comment
Записи соответствуют адресу кода, который обрабатывает конкретный case   -  person 0___________    schedule 27.05.2021
comment
@Jester А, хорошо, неправильно понял вопрос!   -  person th33lf    schedule 27.05.2021
comment
Убедитесь, что вы не используете международную версию этой книги — ее упражнения, как известно, полны серьезных ошибок и кода, который является полной ерундой.   -  person Nate Eldredge    schedule 27.05.2021


Ответы (1)


По-видимому, есть (5 или) 6 cases последовательных значений и вездесущий default.

Таблица переходов содержит один адрес для каждого случая, и вы найдете эти адреса в своем списке.

Например, 0x00000000004005a1 — это адрес этой части:

    4005a1: 48 8d 04 fd 00 00 00     lea 0x0(,%rdi,8),%rax  
    4005a8: 00  
    4005a9: c3                         retq  

Поскольку вторая запись в таблице указывает на тот же адрес, что и адрес по умолчанию (обнаруженный cmp $0x5,%rsi и ja 4005c3 <switch_prob+0x33>), мы можем предположить, что этот case явно не указан. Вот почему это может быть всего 5 cases.

Вычитаемое значение 0x3c может быть символом '<' в ASCII. Также вы можете интерпретировать его в десятичном виде.

Интерпретация каждой ветви switch оставлена ​​вам в качестве упражнения, так как это кажется домашним заданием.

person the busybee    schedule 27.05.2021
comment
спасибо я понял! :) теперь просто интересно, как я могу получить значение регистра переключателей? а также правильно ли я говорю, что значение 3-го столбца - это адрес, на котором заканчивается дело? Если да, то как вы узнали, что это 5 случаев, если у переключателей нет разрыва; между ними (поэтому, как я предполагаю, в таблице только 3 адреса?) - person Megan Darcy; 27.05.2021
comment
Что вы подразумеваете под значением третьего столбца? - person Armali; 28.05.2021
comment
Есть 6 случаев из-за cmp $0x5,%rsi; ja 4005c3. Таким образом, единственными допустимыми значениями для rsi являются значения от 0 до 5. - person Jester; 28.05.2021
comment
@Armali значение в крайней правой части таблицы прыжков, например. 0x00000000004005c3 . Могу ли я предположить, что это означает конец этого дела? - person Megan Darcy; 28.05.2021
comment
@Jester хорошо, спасибо :) и как мне вывести различные значения случаев переключения? :) - person Megan Darcy; 28.05.2021
comment
@MeganDarcy Нет необходимости отмечать конец, потому что это просто таблица переходов. Как после перехода к целевому адресу процессор должен подчиняться конечному адресу? Конец случая достигается, когда процессор выпрыгивает из кода switch. Вы можете нарисовать диаграмму деятельности. - person the busybee; 28.05.2021
comment
@MeganDarcy Есть особый случай с 5-й и 6-й записью. Посмотри долго! - person the busybee; 28.05.2021
comment
@MeganDarcy Вы можете вывести различные значения case, если подумать о первой и второй инструкции, начиная с 0x400590. - person the busybee; 28.05.2021
comment
@MeganDarcy - вы выводите различные значения случаев переключения из вычтенного значения 0x3c, упомянутого Busybee, и верхней границы 5 оттуда, поэтому они равны 60, (61 ,) 62, 63, 64, 65. (61 является избыточным, поскольку указывает на регистр по умолчанию.) - person Armali; 28.05.2021
comment
@thebusybee хорошо, я поняла, спасибо!! - person Megan Darcy; 29.05.2021
comment
@Armali Хорошо, хорошо, я поняла, спасибо!! - person Megan Darcy; 29.05.2021