免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4800 | 回复: 9
打印 上一主题 下一主题

不太理解 (unsigned char) ~0 >> 1 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2009-02-10 18:24 |只看该作者 |倒序浏览
正如题目说((unsigned char) ~0 >> 1 ) ,  第一步:先是把数字0的各个二进制位全部转换为1, 第二步:然后,将结果值转换为unsigned char 类型 ,第三步:然后右移一位。            
其中不明白的是第一步,~0中0又没有存储空间,怎么把它全部转换为1,转换为多少个1,全部到底是多少?
请教请教, 麻烦详细的讲解下~0到底是怎么转换的

论坛徽章:
0
2 [报告]
发表于 2009-02-10 18:57 |只看该作者
不会吧 没人甩我,难道是我没有表达清楚?还是一个无聊帖?

论坛徽章:
0
3 [报告]
发表于 2009-02-10 18:59 |只看该作者
你看看对应的汇编代码

论坛徽章:
0
4 [报告]
发表于 2009-02-10 19:39 |只看该作者
那我试试看

论坛徽章:
0
5 [报告]
发表于 2009-02-10 19:56 |只看该作者
汇编学的不好没有太看懂, 源码是:
#include <stdio.h>

int main() {
        int a;
        a = ((unsigned char)~0 >> 1);

        exit(0);
}

汇编是:
.file   "testhuibian.c"
        .text
.globl main
        .type   main,@function
main:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $8, %esp
        andl    $-16, %esp
        movl    $0, %eax
        subl    %eax, %esp
        movl    $127, -4(%ebp)
        subl    $12, %esp
        pushl   $0
        call    exit
.Lfe1:
        .size   main,.Lfe1-main
        .ident  "GCC: (GNU) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)"
高人帮我分析分析

论坛徽章:
0
6 [报告]
发表于 2009-02-10 21:28 |只看该作者
0默认为int型,占用4个字节,存储为0x00000000
~0的存储值为0xffffffff
转换为unsigned char后存储为0xff,其值为255
>>1就是除以2,存储为0111 1111, 所以为255/2 = 127


很长时间没接触汇编了,也不知道解释的对不对:
注意第(7)句填写了值127
其他的%esp的变化也不是很清楚了,呵呵

.file   "testhuibian.c"
        .text
.globl main
        .type   main,@function
main:
        pushl   %ebp            (1)
        movl    %esp, %ebp    (2) # 这两行是为了保存main函数的frame指针到%ebp

        subl    $8, %esp        (3)  # 当前frame中留出8个字节空间
        andl    $-16, %esp      (4)  # -16的十六进制表示为0xfffffff0
                                            这里让%esp的值以对齐8位字节边界
                                            正常情况下可以假设%esp的值没有变化,
        movl    $0, %eax        (5)
        subl    %eax, %esp     (6)  #  %esp的值没有变化
        movl    $127, -4(%ebp) (7)  #  注意这里的寻址方式

        subl    $12, %esp        (8)

        pushl   $0                (9)
        call    exit                (10)  # 这两句是来调用exit(0)的
.Lfe1:
        .size   main,.Lfe1-main
        .ident  "GCC: (GNU) 3.2.2 20030222 (Red Hat Linux 3.2.2-5)"

   函数frame          # 这里假设栈的增长是从高地址到低地址的

-------- HighAddr
    %ebp
-------                <---  %ebp,%esp  (1)(2)句执行结果
  4个字节  0x000000ff = 127 <--- (7)的执行结果
--------
  4个字节   
--------              <---  %esp (3)的执行结果
  4个字节  
--------
  4个字节   
--------
  4个字节   
--------             <---  %esp (8)的执行结果
            LowAddr
==================================================================

有本书《Professional Assembly Language》可以翻翻,
其中文版叫《汇编语言程序设计》

论坛徽章:
0
7 [报告]
发表于 2009-02-10 21:32 |只看该作者
原帖由 tianxiaogang12 于 2009-2-10 18:24 发表
正如题目说((unsigned char) ~0 >> 1 ) ,  第一步:先是把数字0的各个二进制位全部转换为1, 第二步:然后,将结果值转换为unsigned char 类型 ,第三步:然后右移一位。            
其中不明白的是第一步 ...

有存储,在eax里。
不过,我不明白你为什么不问(1+2),
1和2都没有存储空间啊,怎么得到3呢。。

论坛徽章:
0
8 [报告]
发表于 2009-02-10 21:33 |只看该作者
0的类型是int,而sizeof(int) >= 2, sizeof(unsigned char) = 1,所以(unsigned char)~0为ff(无符号),再右移一位为7f(即127)

论坛徽章:
0
9 [报告]
发表于 2009-02-10 21:53 |只看该作者
原帖由 pFreeStyle 于 2009-2-10 21:28 发表
0默认为int型,占用4个字节,存储为0x00000000
~0的存储值为0xffffffff
转换为unsigned char后存储为0xff,其值为255
>>1就是除以2,存储为0111 1111, 所以为255/2 = 127


很长时间没接触汇编了,也不知 ...

解释的很准确,thanks

论坛徽章:
0
10 [报告]
发表于 2009-02-10 23:13 |只看该作者
恩 谢谢各位了 长见识了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP