c-解释程序集跳转表



我试图逐行解释这个汇编代码在做什么,但当我看到这个汇编中的跳转表时,我发现自己真的很困惑。这取自课本练习题3.63,但没有任何解释——因此我在这里问这个问题。目标是对提供的程序集列表进行逆向工程,并编写可以生成它的C代码(感觉切换语句体(。请帮助:(

教科书是:Randal E.Bryant,David R.O'Hallaron-计算机系统。程序员的视角【第三版】(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调试器,我们可以使用命令x/6gx 0x4006f8检查包含跳转表的六个8字节内存字。GDB打印以下内容:

(gdb(x/6gx 0x4006f8
0x4006f4:0x0000000004005a1 0x00000000004005c3
0x400708:00x00000000004005a10x00000000004005a a
0x400718:0x00000000004005b2 0x00000000004005 bf

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

感谢您的帮助:(

明显存在(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,%rsija 4005c3 <switch_prob+0x33>检测到(,所以我们可以假设该case没有明确列出。这就是为什么它可能只有5个case秒。

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

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

最新更新