链表节点在汇编(炸弹实验室阶段6)



我正在努力弄清楚节点与输入的比较情况。到目前为止,我已经能够辨别出它需要六个整数,它们对应于节点。此外,这些数字不能重复。

我注意到$rbx不断增加 8,在四处寻找后,我能够找到这些:

0x6042e0 <node1>:       0x87    0x03    0x00 = 135
0x6042f0 <node2>:       0x92    0x02    0x00 = 146
0x604300 <node3>:       0x46    0x02    0x00 = 70
0x604310 <node4>:       0x1c    0x02    0x00 = 28
0x604320 <node5>:       0xf5    0x02    0x00 = 245
0x604330 <node6>:       0xc1    0x03    0x00 = 193

我也明白代码正在使用 for 循环来遍历链表。我只是无法弄清楚正在执行什么类型的操作/比较。

这是程序集:

=> 0x00000000004010b0 <+0>:     push   %r13
0x00000000004010b2 <+2>:     push   %r12
0x00000000004010b4 <+4>:     push   %rbp
0x00000000004010b5 <+5>:     push   %rbx
0x00000000004010b6 <+6>:     sub    $0x58,%rsp
0x00000000004010ba <+10>:    lea    0x30(%rsp),%rsi
0x00000000004010bf <+15>:    callq  0x4014cb <read_six_numbers>
0x00000000004010c4 <+20>:    lea    0x30(%rsp),%r12
0x00000000004010c9 <+25>:    mov    $0x0,%r13d
0x00000000004010cf <+31>:    mov    %r12,%rbp
0x00000000004010d2 <+34>:    mov    (%r12),%eax
0x00000000004010d6 <+38>:    sub    $0x1,%eax
0x00000000004010d9 <+41>:    cmp    $0x5,%eax
0x00000000004010dc <+44>:    jbe    0x4010e3 <phase_6+51>
0x00000000004010de <+46>:    callq  0x401495 <explode_bomb>
0x00000000004010e3 <+51>:    add    $0x1,%r13d
0x00000000004010e7 <+55>:    cmp    $0x6,%r13d
0x00000000004010eb <+59>:    je     0x40112a <phase_6+122>
0x00000000004010ed <+61>:    mov    %r13d,%ebx
0x00000000004010f0 <+64>:    movslq %ebx,%rax
0x00000000004010f3 <+67>:    mov    0x30(%rsp,%rax,4),%eax
0x00000000004010f7 <+71>:    cmp    %eax,0x0(%rbp)
0x00000000004010fa <+74>:    jne    0x401101 <phase_6+81>
0x00000000004010fc <+76>:    callq  0x401495 <explode_bomb>
0x0000000000401101 <+81>:    add    $0x1,%ebx
0x0000000000401104 <+84>:    cmp    $0x5,%ebx
0x0000000000401107 <+87>:    jle    0x4010f0 <phase_6+64>
0x0000000000401109 <+89>:    add    $0x4,%r12
0x000000000040110d <+93>:    jmp    0x4010cf <phase_6+31>
0x000000000040110f <+95>:    mov    0x8(%rdx),%rdx
0x0000000000401113 <+99>:    add    $0x1,%eax
0x0000000000401116 <+102>:   cmp    %ecx,%eax
0x0000000000401118 <+104>:   jne    0x40110f <phase_6+95>
0x000000000040111a <+106>:   mov    %rdx,(%rsp,%rsi,2)
0x000000000040111e <+110>:   add    $0x4,%rsi
0x0000000000401122 <+114>:   cmp    $0x18,%rsi
0x0000000000401126 <+118>:   jne    0x40112f <phase_6+127>
0x0000000000401128 <+120>:   jmp    0x401144 <phase_6+148>
0x000000000040112a <+122>:   mov    $0x0,%esi
0x000000000040112f <+127>:   mov    0x30(%rsp,%rsi,1),%ecx
0x0000000000401133 <+131>:   mov    $0x1,%eax
0x0000000000401138 <+136>:   mov    $0x6042e0,%edx
0x000000000040113d <+141>:   cmp    $0x1,%ecx
0x0000000000401140 <+144>:   jg     0x40110f <phase_6+95>
0x0000000000401142 <+146>:   jmp    0x40111a <phase_6+106>
0x0000000000401144 <+148>:   mov    (%rsp),%rbx
0x0000000000401148 <+152>:   mov    %rsp,%rax
0x000000000040114b <+155>:   lea    0x28(%rsp),%rsi
0x0000000000401150 <+160>:   mov    %rbx,%rcx
0x0000000000401153 <+163>:   mov    0x8(%rax),%rdx
0x0000000000401157 <+167>:   mov    %rdx,0x8(%rcx)
0x000000000040115b <+171>:   add    $0x8,%rax
0x000000000040115f <+175>:   mov    %rdx,%rcx
0x0000000000401162 <+178>:   cmp    %rsi,%rax
0x0000000000401165 <+181>:   jne    0x401153 <phase_6+163>
0x0000000000401167 <+183>:   movq   $0x0,0x8(%rdx)
0x000000000040116f <+191>:   mov    $0x5,%ebp
0x0000000000401174 <+196>:   mov    0x8(%rbx),%rax
0x0000000000401178 <+200>:   mov    (%rax),%eax
0x000000000040117a <+202>:   cmp    %eax,(%rbx)
0x000000000040117c <+204>:   jge    0x401183 <phase_6+211>
0x000000000040117e <+206>:   callq  0x401495 <explode_bomb>
0x0000000000401183 <+211>:   mov    0x8(%rbx),%rbx
0x0000000000401187 <+215>:   sub    $0x1,%ebp
0x000000000040118a <+218>:   jne    0x401174 <phase_6+196>
0x000000000040118c <+220>:   add    $0x58,%rsp
0x0000000000401190 <+224>:   pop    %rbx
0x0000000000401191 <+225>:   pop    %rbp
0x0000000000401192 <+226>:   pop    %r12
0x0000000000401194 <+228>:   pop    %r13
0x0000000000401196 <+230>:   retq   

提前感谢您的帮助。

这发生在 163 和 181 之间吗?只是试图找到一个起点和方向。

该循环是从线性递增的地址(add $8, %rax(读取,但写入y=*input++; x->next = y; x=y;或类似的东西。 这可能是从指针数组构建链表? 奇怪。

无论如何,遍历链表的循环的关键特征是p = p->next在 asm 中,查找具有涉及目标寄存器的寻址模式的负载。 (或者有时它可能会加载到不同的寄存器中,然后稍后的mov可以复制回同一寄存器。

例如<+95>: mov 0x8(%rdx),%rdx看起来像一个微小循环的一部分,该循环在列表中前进ECX步骤。

然后在循环之后,它将最终指针存储到堆栈上的数组中? 正在进行一些混淆的数组索引,其中rsiadd $4,%rsi递增,但用于比例因子为 2 且具有mov %rdx,(%rsp,%rsi,2)的 qword 存储。

我还没有检查过这个,但我怀疑代码正在通过为每个整数分别"索引"到链表中来检查您的整数序列,并记录它在这么多步骤后到达的元素。 然后将其记录在稍后将使用的指针数组中。

由于链表不是随机访问的数据结构,因此使用整数编制索引意味着在指针跟踪循环中循环多次。 这将解释将指针存储到数组中的循环中的链表迭代循环。

是的,我认为这是对的。 在外部循环主体内部可能存在break条件,但是在此底部,它有一个mov $0x6042e0,%edx,它将静态地址(可能是第一个节点的(再次放入RDX,并跳回到内部循环的顶部。

最新更新