x86-64 中的数组
Arrays in x86-64
好的,我对这里发生的事情有一个很好的了解。我输入 6 个 char 字符,它假设等于 $0x3a,即 58。因此数组遍历每个字符并执行 & 和 $0xf,即 15。然后我没有得到的是它在第 39 行所做的事情。例如,如果我输入 b 然后对其执行 & 0xf,它变为 2,在 39 行之后,%ecx 变为 6,我不知道该计算是如何完成的。我认为第 39 行是 x + 4y,所以 %rsi + (%rdx * 4)。有人知道第 39 行到底发生了什么吗?
Dump of assembler code for function phase_5:
0x000055555555547d <+0>: push %rbx
0x000055555555547e <+1>: mov %rdi,%rbx
0x0000555555555481 <+4>: callq 0x5555555556fe <string_length>
0x0000555555555486 <+9>: cmp [=10=]x6,%eax
0x0000555555555489 <+12>: jne 0x5555555554bc <phase_5+63>
0x000055555555548b <+14>: mov %rbx,%rax
0x000055555555548e <+17>: lea 0x6(%rbx),%rdi
0x0000555555555492 <+21>: mov [=10=]x0,%ecx
0x0000555555555497 <+26>: lea 0x1622(%rip),%rsi # 0x555555556ac0 <array.3416>
0x000055555555549e <+33>: movzbl (%rax),%edx
0x00005555555554a1 <+36>: and [=10=]xf,%edx
0x00005555555554a4 <+39>: add (%rsi,%rdx,4),%ecx
0x00005555555554a7 <+42>: add [=10=]x1,%rax
0x00005555555554ab <+46>: cmp %rdi,%rax
0x00005555555554ae <+49>: jne 0x55555555549e <phase_5+33>
0x00005555555554b0 <+51>: cmp [=10=]x3a,%ecx
0x00005555555554b3 <+54>: je 0x5555555554ba <phase_5+61>
0x00005555555554b5 <+56>: callq 0x555555555a14 <explode_bomb>
0x00005555555554ba <+61>: pop %rbx
0x00005555555554bb <+62>: retq
0x00005555555554bc <+63>: callq 0x555555555a14 <explode_bomb>
0x00005555555554c1 <+68>: jmp 0x55555555548b <phase_5+14>
数组 'array.3416' 包含 16 个 4 字节值。
您输入的字母(它们右边的十六进制数字)用作该数组中的索引。
索引可以有 16 个可能的索引值:0 .. 15.
第36行的and操作取输入字符最右边的十六进制数字(ASCII码&0xF: '@'=>0, 'A'=>1, 'B'=>2, ..., 'O'=>15,'P'=>0,'Q'=>1,...)。
然后它从数组中获取相应的值并同时(在第 39 行)将所有 6 个数组值相加,通过循环每个密码字母一个。
好的,我对这里发生的事情有一个很好的了解。我输入 6 个 char 字符,它假设等于 $0x3a,即 58。因此数组遍历每个字符并执行 & 和 $0xf,即 15。然后我没有得到的是它在第 39 行所做的事情。例如,如果我输入 b 然后对其执行 & 0xf,它变为 2,在 39 行之后,%ecx 变为 6,我不知道该计算是如何完成的。我认为第 39 行是 x + 4y,所以 %rsi + (%rdx * 4)。有人知道第 39 行到底发生了什么吗?
Dump of assembler code for function phase_5:
0x000055555555547d <+0>: push %rbx
0x000055555555547e <+1>: mov %rdi,%rbx
0x0000555555555481 <+4>: callq 0x5555555556fe <string_length>
0x0000555555555486 <+9>: cmp [=10=]x6,%eax
0x0000555555555489 <+12>: jne 0x5555555554bc <phase_5+63>
0x000055555555548b <+14>: mov %rbx,%rax
0x000055555555548e <+17>: lea 0x6(%rbx),%rdi
0x0000555555555492 <+21>: mov [=10=]x0,%ecx
0x0000555555555497 <+26>: lea 0x1622(%rip),%rsi # 0x555555556ac0 <array.3416>
0x000055555555549e <+33>: movzbl (%rax),%edx
0x00005555555554a1 <+36>: and [=10=]xf,%edx
0x00005555555554a4 <+39>: add (%rsi,%rdx,4),%ecx
0x00005555555554a7 <+42>: add [=10=]x1,%rax
0x00005555555554ab <+46>: cmp %rdi,%rax
0x00005555555554ae <+49>: jne 0x55555555549e <phase_5+33>
0x00005555555554b0 <+51>: cmp [=10=]x3a,%ecx
0x00005555555554b3 <+54>: je 0x5555555554ba <phase_5+61>
0x00005555555554b5 <+56>: callq 0x555555555a14 <explode_bomb>
0x00005555555554ba <+61>: pop %rbx
0x00005555555554bb <+62>: retq
0x00005555555554bc <+63>: callq 0x555555555a14 <explode_bomb>
0x00005555555554c1 <+68>: jmp 0x55555555548b <phase_5+14>
数组 'array.3416' 包含 16 个 4 字节值。
您输入的字母(它们右边的十六进制数字)用作该数组中的索引。
索引可以有 16 个可能的索引值:0 .. 15.
第36行的and操作取输入字符最右边的十六进制数字(ASCII码&0xF: '@'=>0, 'A'=>1, 'B'=>2, ..., 'O'=>15,'P'=>0,'Q'=>1,...)。
然后它从数组中获取相应的值并同时(在第 39 行)将所有 6 个数组值相加,通过循环每个密码字母一个。