assembly - 组装测验 - 阶段 6
问题描述
我一直在解决关于汇编代码的测验,但是 Quiz6(第 6 阶段)对我来说真的很难弄清楚它在做什么。我刚刚发现阶段 6 的输入是六个整数,每个整数都是相同的,并且小于等于 6。我在下面的代码行中写了一些其他细节。
Phase_6 说什么:
Dump of assembler code for function phase_6:
=> 0x00005555555554fd <+0>: push %r14
0x00005555555554ff <+2>: push %r13
0x0000555555555501 <+4>: push %r12
0x0000555555555503 <+6>: push %rbp
0x0000555555555504 <+7>: push %rbx
0x0000555555555505 <+8>: sub $0x60,%rsp
0x0000555555555509 <+12>: mov %fs:0x28,%rax
0x0000555555555512 <+21>: mov %rax,0x58(%rsp)
0x0000555555555517 <+26>: xor %eax,%eax
0x0000555555555519 <+28>: mov %rsp,%r13
0x000055555555551c <+31>: mov %r13,%rsi
0x000055555555551f <+34>: callq 0x555555555aba <read_six_numbers>
0x0000555555555524 <+39>: mov %r13,%r12
0x0000555555555527 <+42>: mov $0x0,%r14d
0x000055555555552d <+48>: jmp 0x555555555554 <phase_6+87>
0x000055555555552f <+50>: callq 0x555555555a7e <explode_bomb>
0x0000555555555534 <+55>: jmp 0x555555555563 <phase_6+102>
0x0000555555555536 <+57>: add $0x1,%ebx
0x0000555555555539 <+60>: cmp $0x5,%ebx
0x000055555555553c <+63>: jg 0x555555555550 <phase_6+83>
0x000055555555553e <+65>: movslq %ebx,%rax
0x0000555555555541 <+68>: mov (%rsp,%rax,4),%eax
0x0000555555555544 <+71>: cmp %eax,0x0(%rbp)
0x0000555555555547 <+74>: jne 0x555555555536 <phase_6+57>
0x0000555555555549 <+76>: callq 0x555555555a7e <explode_bomb>
// Upper cods seems to test the identicality and integers are under equal 6
//And I have no idea what are below codelines do. From here...
0x000055555555554e <+81>: jmp 0x555555555536 <phase_6+57>
0x0000555555555550 <+83>: add $0x4,%r13
0x0000555555555554 <+87>: mov %r13,%rbp
0x0000555555555557 <+90>: mov 0x0(%r13),%eax
0x000055555555555b <+94>: sub $0x1,%eax
0x000055555555555e <+97>: cmp $0x5,%eax
0x0000555555555561 <+100>: ja 0x55555555552f <phase_6+50>
0x0000555555555563 <+102>: add $0x1,%r14d
0x0000555555555567 <+106>: cmp $0x6,%r14d
0x000055555555556b <+110>: je 0x555555555572 <phase_6+117>
0x000055555555556d <+112>: mov %r14d,%ebx
0x0000555555555570 <+115>: jmp 0x55555555553e <phase_6+65>
0x0000555555555572 <+117>: lea 0x18(%r12),%rcx
0x0000555555555577 <+122>: mov $0x7,%edx
0x000055555555557c <+127>: mov %edx,%eax
0x000055555555557e <+129>: sub (%r12),%eax
0x0000555555555582 <+133>: mov %eax,(%r12)
0x0000555555555586 <+137>: add $0x4,%r12
0x000055555555558a <+141>: cmp %r12,%rcx
0x000055555555558d <+144>: jne 0x55555555557c <phase_6+127>
0x000055555555558f <+146>: mov $0x0,%esi
0x0000555555555594 <+151>: jmp 0x5555555555b0 <phase_6+179>
0x0000555555555596 <+153>: mov 0x8(%rdx),%rdx
0x000055555555559a <+157>: add $0x1,%eax
0x000055555555559d <+160>: cmp %ecx,%eax
0x000055555555559f <+162>: jne 0x555555555596 <phase_6+153>
0x00005555555555a1 <+164>: mov %rdx,0x20(%rsp,%rsi,8)
0x00005555555555a6 <+169>: add $0x1,%rsi
0x00005555555555aa <+173>: cmp $0x6,%rsi
0x00005555555555ae <+177>: je 0x5555555555c6 <phase_6+201>
0x00005555555555b0 <+179>: mov (%rsp,%rsi,4),%ecx
0x00005555555555b3 <+182>: mov $0x1,%eax
0x00005555555555b8 <+187>: lea 0x202c71(%rip),%rdx # 0x555555758230 <node1>
0x00005555555555bf <+194>: cmp $0x1,%ecx
0x00005555555555c2 <+197>: jg 0x555555555596 <phase_6+153>
0x00005555555555c4 <+199>: jmp 0x5555555555a1 <phase_6+164>
0x00005555555555c6 <+201>: mov 0x20(%rsp),%rbx
0x00005555555555cb <+206>: mov 0x28(%rsp),%rax
0x00005555555555d0 <+211>: mov %rax,0x8(%rbx)
0x00005555555555d4 <+215>: mov 0x30(%rsp),%rdx
0x00005555555555d9 <+220>: mov %rdx,0x8(%rax)
0x00005555555555dd <+224>: mov 0x38(%rsp),%rax
0x00005555555555e2 <+229>: mov %rax,0x8(%rdx)
0x00005555555555e6 <+233>: mov 0x40(%rsp),%rdx
0x00005555555555eb <+238>: mov %rdx,0x8(%rax)
0x00005555555555ef <+242>: mov 0x48(%rsp),%rax
0x00005555555555f4 <+247>: mov %rax,0x8(%rdx)
0x00005555555555f8 <+251>: movq $0x0,0x8(%rax)
0x0000555555555600 <+259>: mov $0x5,%ebp
0x0000555555555605 <+264>: jmp 0x555555555610 <phase_6+275>
// ...To Here
//I think this block is compareing $rbx, *($rbx + 8), .... with ($rbx)
//but gdb says can't read the memory *($rbx + 8), *(*($rbx + 8) + 8), ...things.
//Only it reads $rbx
0x0000555555555607 <+266>: mov 0x8(%rbx),%rbx
0x000055555555560b <+270>: sub $0x1,%ebp
0x000055555555560e <+273>: je 0x555555555621 <phase_6+292>
0x0000555555555610 <+275>: mov 0x8(%rbx),%rax
0x0000555555555614 <+279>: mov (%rax),%eax
0x0000555555555616 <+281>: cmp %eax,(%rbx)
0x0000555555555618 <+283>: jge 0x555555555607 <phase_6+266>
0x000055555555561a <+285>: callq 0x555555555a7e <explode_bomb>
0x000055555555561f <+290>: jmp 0x555555555607 <phase_6+266>
0x0000555555555621 <+292>: mov 0x58(%rsp),%rax
0x0000555555555626 <+297>: xor %fs:0x28,%rax
0x000055555555562f <+306>: jne 0x55555555563e <phase_6+321>
0x0000555555555631 <+308>: add $0x60,%rsp
0x0000555555555635 <+312>: pop %rbx
0x0000555555555636 <+313>: pop %rbp
0x0000555555555637 <+314>: pop %r12
0x0000555555555639 <+316>: pop %r13
0x000055555555563b <+318>: pop %r14
0x000055555555563d <+320>: retq
0x000055555555563e <+321>: callq 0x555555554e90 <__stack_chk_fail@plt>
End of assembler dump.
我也尝试until *0x0000555555555618
并ni
识别流程,但是......不知道规则是什么......
解决方案
我找到了。
此阶段具有大小为 16 字节的链表节点。(注意mov 0x8(%rbx),%rbx
指针追踪p = p->next
qword 从相对于节点开始的偏移量 +8 加载。
我们可以忽略指针的高 dword,因为它们都是相同的(x86 是 little-endian),只需查看 GDBeXamine
格式为的每个节点的前 3 个 dword /3x
,使用 32 位元素的默认大小.
Breakpoint 1, 0x00005555555554fd in phase_6 ()
(gdb) until *0x0000555555555618
0x0000555555555618 in phase_6 ()
(gdb) x/3x $rdx-16
0x555555758230 <node1>: 0x00000189 0x00000001 0x00000000
(gdb) x/3x $rdx
0x555555758240 <node2>: 0x00000113 0x00000002 0x55758230
(gdb) x/3x $rdx+16
0x555555758250 <node3>: 0x0000007f 0x00000003 0x55758240
(gdb) x/3x $rdx+32
0x555555758260 <node4>: 0x000000ff 0x00000004 0x55758250
(gdb) x/3x $rdx+48
0x555555758270 <node5>: 0x000001fd 0x00000005 0x55758260
(gdb) x/3x $rbx
0x555555758110 <node6>: 0x000003b3 0x00000006 0x55758270
当我给出1 2 3 4 5 6
输入时,程序会按6 5 4 3 2 1
. 如果输入是1 5 3 4 2 6
,则检查6 2 4 3 5 1
.
输入 = a, b, c, d, e ->检查 = 7-a, 7-b, 7-c, 7-d, 7-e
有效性检查由
0x0000555555555616 <+281>: cmp %eax,(%rbx)
0x0000555555555618 <+283>: jge 0x555555555607 <phase_6+266>
如果 的值node 7-a
大于node 7-b
,则程序说 OK。如果不是,否。
而每个节点的值是...
0x555555758230 <node1>: 0x00000189
0x555555758240 <node2>: 0x00000113
0x555555758250 <node3>: 0x0000007f
0x555555758260 <node4>: 0x000000ff
0x555555758270 <node5>: 0x000001fd
0x555555758110 <node6>: 0x000003b3
所以答案是1 2 6 5 3 4
!
推荐阅读
- python - 将点积应用于 3D 数组中的所有列
- sqlite - 在 React Native 中更新表时如何刷新从 SQLite 检索到的数据?
- mpdf - 上传多个文件时应用字体的 Light 版本
- nvm - 如何定位或查找 nvm(节点版本管理器)文件
- angular - 数据在 ng 多选下拉列表中不可见
- llvm - 如何使用 llvm elementwise atomic intrinsics?
- angular - 无法绑定到“formGroup”,因为它不是“form”的已知属性。角 7
- android - 应用 ProGuard 规则后未显示 Admob 广告
- c++11 - 无法找到错误语句树:子数组中的最小值
- ionic-framework - Ionic 4:带有路由的选项卡不显示内容