解释装配跳转表

Meg*_*rcy 2 c x86 assembly switch-statement jump-table

我试图逐行解释这个汇编代码在做什么,但是当我看到这个汇编中的跳转表时,我发现自己真的很困惑。这是从教科书练习题 3.63 中获取的,但没有解释 -因此,为什么我在这里问它。目标是对提供的汇编列表进行逆向工程并编写可以生成它的 C 代码(感觉 switch 语句体)。请帮忙 :(

教科书是: Randal E. Bryant, David R. O'Hallaron - 计算机系统。程序员的观点 [第 3 版](2016 年,Pearson)

qn 3.63

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

我不确定如何“解码”它或如何知道它指向哪里。

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  
Run Code Online (Sandbox Code Playgroud)

跳转表驻留在不同的内存区域。从第 5 行的间接跳转我们可以看出,跳转表从地址 0x4006f8 开始。使用 GDB 调试器,我们可以使用命令 x/6gx 0x4006f8 检查构成跳转表的 6 个 8 字节内存字。GDB 打印以下内容:

(GDB)X / 6gx 0x4006f8
0x4006f8:0x00000000004005a1 0x00000000004005c3
0x400708:0x00000000004005a1 0x00000000004005aa
0x400718:0x00000000004005b2 0x00000000004005bf

我知道这一行 40059a: ff 24 f5 f8 06 40 00 jmpq *0x4006f8(,%rsi,8)
正在跳转到表,但我不确定如何
1) 解释跳转表 [每个地址对应什么, 6 个值中的每一个是什么
意思/保持]
2)对其进行逆向工程以获得 switch 语句的不同情况。

任何帮助表示赞赏,谢谢:)

the*_*bee 6

显然有(5 或)6case个连续值,并且无所不在default

跳转表每个案例包含一个地址,您将在列表中找到这些地址。

比如0x00000000004005a1就是这部分的地址:

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

因为表中的第二个条目指向与默认地址相同的地址(由cmp $0x5,%rsi和检测ja 4005c3 <switch_prob+0x33>),我们可以假设这case没有明确列出。这就是为什么它可能只有 5case秒。

减去的值 0x3c 可能是'<'ASCII 中的字符。你也可能想用十进制来解释它。

对每个分支的解释switch留给您作为练习,因为这似乎是家庭作业。