学习高手的代码风格之(二)---abs反汇编分析,理解为何abs会返回负数


abs是我们常用的取绝对值的函数,并且实现也很简单,按照以往自己实现abs功能的时候,一定会选择判断输入是否大于0,然后分别处理,但是今天对abs的分析,在不使用判断语句的情况下,对一个数取了绝对值,让我对计算机处理数的方法有了更深的了解。
以及理解为何abs会在一定条件下返回一个负数。

函数介绍

功 能: 求整数的绝对值
头文件:stdlib.h
函数原型:int abs(int i);
/来自百度百科/

反汇编分析

4B2F4810                 mov     edi, edi        ;微软给我们下HOOK的地方
4B2F4812                 push    ebp			 ; 保存ebp
4B2F4813                 mov     ebp, esp		 ;建立新的堆栈
4B2F4815                 mov     eax, [ebp+arg_0];将要进行绝对值转换的数移动到eax
4B2F4818                 cdq					 ;将edx的每一位至为eax的最高位,也就是要转换的数的符号位
4B2F4819                 xor     eax, edx		 ;将要处理的数和符号位异或,如果是正数,则不会发生改变,负数则取反,并将符号位至为0
4B2F481B                 sub     eax, edx		 ;由于数在计算机中以补码的形式存在,补码转原码应该取反加1,所以此处负数需要+1,正数的话edx为0不会影响
4B2F481D                 pop     ebp 			 ;恢复ebp
4B2F481E                 retn

学到的知识

短短的几行代码,并没有用到判断语句就直接计算出了数的绝对值,方法值得学习。但是关于代码中对堆栈的处理,个人觉得是否有一些的多余,因为所有的操作都是在寄存器中进行的,所以是否可以直接去掉三行代码,让代码变得更加精简呢?以及可能算bug的一个存在,就是会返回一个负数。

为何abs会返回负数

abs的作用为返回一个数的绝对值,绝对值肯定是非负数,但是我们都知道,例如一个char,他的取值范围是-128~127,那么当我们输入一个abs(-128)的时候程序会返回什么呢?答案是-128。为什么会出现这种情况呢?
在对应上来讲,由于正数的个数比负数多一个,所以不是每一个负数都能找到自己的对应正数。所以128无法返回,但是为何-128输入之后输出仍然为128呢?是因为没处理吗?当然不是。

依据上文的代码,我们可以做如下推理
eax=-128=1000 0000=0x80
edx=1111 1111=0xFF
xor eax,edx -> eax=0111 1111=0x7F
sub eax,edx -> eax=1000 0000=-128
所以此处不是因为没有处理,而是照样处理了,只是最大的负数经过这样的流程处理之后,仍然还是原数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值