zoukankan      html  css  js  c++  java
  • 编写安全代码:有符号数和无符号数的移位区别右移

    本文的copyleft归gfree.wind@gmail.com所有,使用GPL发布,可以自由拷贝,转载。但转载请保持文档的完整性,注明原作者及原链接,严禁用于任何商业用途。
    作者:gfree.wind@gmail.com
    博客:linuxfocus.blog.chinaunix.net
        

    (下面所有的测试为Linux平台,gcc编译器)
    #include <stdio.h>
    
    #include <stdlib.h>
    
    
    
    
    
    int main ()
    
    {
    
        int a = 0x80000000;
    
        unsigned int b = 0x80000000;
    
    
    
        printf("a right shift value is 0x%X\n", a >> 1);
    
        printf("b right shift value is 0x%X\n", b >> 1);
    
    
    
        return 0;
    
    }
    输出结果为
    [root@Lnx99 test]#./a.out
    
    a right shift value is 0xC0000000
    
    b right shift value is 0x40000000
    为什么结果不同呢?
    查看汇编代码
    Dump of assembler code for function main:
    0x080483c4 <main+0>: push %ebp
    0x080483c5 <main+1>: mov %esp,%ebp
    0x080483c7 <main+3>: and $0xfffffff0,%esp
    0x080483ca <main+6>: sub $0x20,%esp
    0x080483cd <main+9>: movl $0x80000000,0x18(%esp)
    0x080483d5 <main+17>: movl $0x80000000,0x1c(%esp)
    0x080483dd <main+25>: mov 0x18(%esp),%eax
    0x080483e1 <main+29>: mov %eax,%edx
    0x080483e3 <main+31>: sar %edx
    0x080483e5 <main+33>: mov $0x80484e4,%eax
    0x080483ea <main+38>: mov %edx,0x4(%esp)
    0x080483ee <main+42>: mov %eax,(%esp)
    0x080483f1 <main+45>: call 0x80482f4 <printf@plt>
    0x080483f6 <main+50>: mov 0x1c(%esp),%eax
    0x080483fa <main+54>: mov %eax,%edx
    0x080483fc <main+56>: shr %edx
    0x080483fe <main+58>: mov $0x8048501,%eax
    0x08048403 <main+63>: mov %edx,0x4(%esp)
    0x08048407 <main+67>: mov %eax,(%esp)
    0x0804840a <main+70>: call 0x80482f4 <printf@plt>
    0x0804840f <main+75>: mov $0x0,%eax
    0x08048414 <main+80>: leave
    0x08048415 <main+81>: ret
    End of assembler dump.
    其中红色代码对应的是a>>1,sar为算术右移,使用符号位补位,在这里补的全是1.
    蓝色代码对应的是b>>1,shr为逻辑右移,使用0补位。
     
    在平时的工作中,一般情况下,我们所期待的移位操作应该为逻辑右移,所以在使用移位操作时,一定要注意操作数的类型,一定要保证为无符号数。这样结果才是我们所期待的结果。
     
    查了查资料,根据大多数的说法。C标准没有规定有符号数的右移如何处理。那么对于有符号数的右移处理,就由编译器决定。
        
    作者:wanglei_wan
        
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    Mac下安装zsh(Oh My ZSH)的shell,替代原有的bash
    Mac下配置环境变量重启后不生效解决(.bash_profile vs .bashrc)(bash/zsh下不加载.bashrc问题解决)
    Mac下配置环境变量(转)
    Jenkins配置Publish Junit test result report(转)
    Mac下配置Java Web开发环境(Mac 10.12)
    Mac下配置idea(Mac 10.12)
    Sublime Text 3安装插件(Mac 10.12)
    Sublime Text 3新建工程
    Mac下快速新建txt文件
    Mac下配置maven和集成到ecclipse(Mac 10.12)
  • 原文地址:https://www.cnblogs.com/because/p/2711976.html
Copyright © 2011-2022 走看看