解释程序集跳转 table
Interpreting an assembly jump table
我试图逐行解释这段汇编代码在做什么,但当我看到这个跳转 table 时,我发现自己真的很困惑,它位于 assembly.This 中,取自教科书练习题 3.63 但没有解释 - 因此我在这里问它。目标是对提供的汇编列表进行逆向工程并编写可以生成它的 C 代码(感觉 switch 语句体)。请帮助:(
教科书是:Randal E. Bryant, David R. O'Hallaron - Computer Systems。程序员的视角 [第 3 版](2016 年,Pearson)
qn 3.63
long switch_prob(long x, long n) {
long result = x;
switch(n) {
/* Fill in code here */
}
return result;
}
我不确定如何 'decode' 它或如何知道它指向哪里。
0000000000400590 <switch_prob>:
400590: 48 83 ee 3c sub [=12=]x3c,%rsi
400594: 48 83 fe 05 cmp [=12=]x5,%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 [=12=]x3,%rax
4005b1: c3 retq
4005b2: 48 89 f8 mov %rdi,%rax
4005b5: 48 c1 e0 04 shl [=12=]x4,%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
跳转table驻留在不同的内存区域。我们从第5行的间接跳转可以看出,跳转table是从地址0x4006f8开始的。使用 GDB 调试器,我们可以使用命令 x/6gx 0x4006f8 检查包含跳转 table 的六个 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)
正在跳转到 table 但我不确定如何
1)解释跳转table【每个地址对应什么,6个值各代表什么
mean/hold]
2) 对其进行逆向工程以获取 switch 语句的不同情况。
感谢任何帮助,谢谢:)
显然有(5 或)6 个 case
的连续值,以及无所不在的 default
.
跳转 table 每个案例包含一个地址,您将在您的列表中找到这些地址。
比如0x00000000004005a1就是这部分的地址:
4005a1: 48 8d 04 fd 00 00 00 lea 0x0(,%rdi,8),%rax
4005a8: 00
4005a9: c3 retq
因为 table 中的第二个条目指向与默认地址相同的地址(由 cmp [=13=]x5,%rsi
和 ja 4005c3 <switch_prob+0x33>
检测到),我们可以假设这个 case
没有明确列出。这就是为什么它可能只有 5 case
秒。
减去的值0x3c可能是ASCII中的字符'<'
。你也可能想用十进制来解释它。
switch
每个分支的解释留给你作为练习,因为这似乎是作业。
我试图逐行解释这段汇编代码在做什么,但当我看到这个跳转 table 时,我发现自己真的很困惑,它位于 assembly.This 中,取自教科书练习题 3.63 但没有解释 - 因此我在这里问它。目标是对提供的汇编列表进行逆向工程并编写可以生成它的 C 代码(感觉 switch 语句体)。请帮助:(
教科书是:Randal E. Bryant, David R. O'Hallaron - Computer Systems。程序员的视角 [第 3 版](2016 年,Pearson)
qn 3.63
long switch_prob(long x, long n) {
long result = x;
switch(n) {
/* Fill in code here */
}
return result;
}
我不确定如何 'decode' 它或如何知道它指向哪里。
0000000000400590 <switch_prob>:
400590: 48 83 ee 3c sub [=12=]x3c,%rsi
400594: 48 83 fe 05 cmp [=12=]x5,%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 [=12=]x3,%rax
4005b1: c3 retq
4005b2: 48 89 f8 mov %rdi,%rax
4005b5: 48 c1 e0 04 shl [=12=]x4,%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
跳转table驻留在不同的内存区域。我们从第5行的间接跳转可以看出,跳转table是从地址0x4006f8开始的。使用 GDB 调试器,我们可以使用命令 x/6gx 0x4006f8 检查包含跳转 table 的六个 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)
正在跳转到 table 但我不确定如何
1)解释跳转table【每个地址对应什么,6个值各代表什么
mean/hold]
2) 对其进行逆向工程以获取 switch 语句的不同情况。
感谢任何帮助,谢谢:)
显然有(5 或)6 个 case
的连续值,以及无所不在的 default
.
跳转 table 每个案例包含一个地址,您将在您的列表中找到这些地址。
比如0x00000000004005a1就是这部分的地址:
4005a1: 48 8d 04 fd 00 00 00 lea 0x0(,%rdi,8),%rax
4005a8: 00
4005a9: c3 retq
因为 table 中的第二个条目指向与默认地址相同的地址(由 cmp [=13=]x5,%rsi
和 ja 4005c3 <switch_prob+0x33>
检测到),我们可以假设这个 case
没有明确列出。这就是为什么它可能只有 5 case
秒。
减去的值0x3c可能是ASCII中的字符'<'
。你也可能想用十进制来解释它。
switch
每个分支的解释留给你作为练习,因为这似乎是作业。