CSAPP 3e: Bomb lab (phase_4)

当筵意气临九霄,星离雨散不终朝。这篇文章主要讲述CSAPP 3e: Bomb lab (phase_4)相关的知识,希望能为你提供帮助。
先贴出phase_4的代码:

0000000000400fce < func4> :; %rdi=num_0; %rsi=0; %rdx=0xe; 400fce:48 83 ec 08sub$0x8,%rsp 400fd2:89 d0mov%edx,%eax; %eax=0xe; 400fd4:29 f0sub%esi,%eax; %eax=0xe-0==e; 400fd6:89 c1mov%eax,%ecx; %ecx=e; 400fd8:c1 e9 1fshr$0x1f,%ecx; 右移31位,注意shr是逻辑右移!!! 400fdb:01 c8add%ecx,%eax; 也就是如果%eax为正数则不变,为负数则+1; 400fdd:d1 f8sar%eax; (算术)右移1位,即%eax/2; 400fdf:8d 0c 30lea(%rax,%rsi,1),%ecx; %ecx=e; 400fe2:39 f9cmp%edi,%ecx 400fe4:7e 0cjle400ff2 < func4+0x24> ; if(cx< =di)continue; else %edx=-(1+%rcx); 400fe6:8d 51 fflea-0x1(%rcx),%edx 400fe9:e8 e0 ff ff ffcallq400fce < func4> ; %eax=2*%eax. 400fee:01 c0add%eax,%eax; 注意这里,自身调用func4后的操作,%eax乘以2了,然后ret。 400ff0:eb 15jmp401007 < func4+0x39> 400ff2:b8 00 00 00 00mov$0x0, %eax; 注意这里,%eax=0,然后ret返回。这里才开始停止调用自身。重点中的重点!!! 400ff7:39 f9cmp%edi,%ecx 400ff9:7d 0cjge401007 < func4+0x39> 400ffb:8d 71 01lea0x1(%rcx),%esi 400ffe:e8 cb ff ff ffcallq400fce < func4> ; %eax=2*%eax+1. 401003:8d 44 00 01lea0x1(%rax,%rax,1),%eax; 注意这里,自身调用func4后的操作,%eax乘以2并加1,然后ret。 401007:48 83 c4 08add$0x8,%rsp 40100b:c3retq000000000040100c < phase_4> : 40100c:48 83 ec 18sub$0x18,%rsp 401010:48 8d 4c 24 0clea0xc(%rsp),%rcx; 这里跟之前的一样,(%rsp+0xc)存储第二个数字,令其为num_1; 401015:48 8d 54 24 08lea0x8(%rsp),%rdx; (%rsp+8)存储第一数,令其为num_0. 40101a:be cf 25 40 00mov$0x4025cf,%esi; 查看内存为字符串"%d %d",说明还是输入两个数。 40101f:b8 00 00 00 00mov$0x0,%eax 401024:e8 c7 fb ff ffcallq400bf0 < [email  protected]> 401029:83 f8 02cmp$0x2,%eax; sscanf正常返回值为2,条件跳转不执行。 40102c:75 07jne401035 < phase_4+0x29> 40102e:83 7c 24 08 0ecmpl$0xe,0x8(%rsp); if(num_0 < = 14) jmp; else to bomb; 401033:76 05jbe40103a < phase_4+0x2e> ; 所以这里要求num_0必须小于等于14 401035:e8 00 04 00 00callq40143a < explode_bomb> 40103a:ba 0e 00 00 00mov$0xe,%edx 40103f:be 00 00 00 00mov$0x0,%esi 401044:8b 7c 24 08mov0x8(%rsp),%edi; 这里是针对num_0的运算,调用了函数func4,这里是重点!! 401048:e8 81 ff ff ffcallq400fce < func4> 40104d:85 c0test%eax,%eax; if(%eax==0)jmp; else to bomb; 40104f:75 07jne401058 < phase_4+0x4c> ; 也就是call func4的返回值必须为0,否则爆炸。 401051:83 7c 24 0c 00cmpl$0x0,0xc(%rsp) 401056:74 05je40105d < phase_4+0x51> ; 这里比较num_1,要求第二个数必须等于0。 401058:e8 dd 03 00 00callq40143a < explode_bomb> 40105d:48 83 c4 18add$0x18,%rsp 401061:c3retq

【CSAPP 3e: Bomb lab (phase_4)】指令的讲解在注释里了,但是想讲讲我的另一种分析方法:
 
CSAPP 3e: Bomb lab (phase_4)

文章图片

途中通道的意思,表述可能不对,可以理解为是一个运行的路程吧。
为了保证总的返回值是0,所以只能走a,c通道(路程),由此可以计算出%ecx的值,只要在这几次计算中有一次num_0(即输入的第一个数)等于%ecx的值,就可以正确返回0了。
所以最终的答案为 "7 0","3 0","1 0","0 0"。
到这里,就结束了。

    推荐阅读