Chinaunix

标题: 内核中计算高低端内存界限896M值的迷惑,求解! [打印本页]

作者: shaohui973    时间: 2014-04-12 11:12
标题: 内核中计算高低端内存界限896M值的迷惑,求解!
RT。
os: linux
version:2.4.0
在setup_arch()中
      
         if(max_low_pfn > MAX_MEM_PFN)
               max_low_pfn = MAX_MEM_PFN;

#define MAX_MEM_PFN PFN_DOWN(MAXMEM)
#define MAXMEM (unsigned long)(-0xc0000000 - 128 << 20)         /* -3G - 128M */

我写了一个测试程序
int main()
{
    unsigned long  a = -0xc0000000 - 128 << 20;

    printf("0x%016x.\n", a);

    return 0;
}

结果,打印的值为0xf8000000(编译器直接优化成0xf8000000),而不是0x38000000(896M)
290 00000000004004c4 <main>:
291   4004c4:   55                      push   %rbp
292   4004c5:   48 89 e5                mov    %rsp,%rbp
293   4004c8:   48 83 ec 10             sub    $0x10,%rsp
294   4004cc:   c7 45 f8 00 00 00 f8    movl   $0xf8000000,-0x8(%rbp)
295   4004d3:   c7 45 fc 00 00 00 00    movl   $0x0,-0x4(%rbp)
296   4004da:   b8 f8 05 40 00          mov    $0x4005f8,%eax
297   4004df:   48 8b 55 f8             mov    -0x8(%rbp),%rdx
298   4004e3:   48 89 d6                mov    %rdx,%rsi
299   4004e6:   48 89 c7                mov    %rax,%rdi
300   4004e9:   b8 00 00 00 00          mov    $0x0,%eax
301   4004ee:   e8 c5 fe ff ff          callq  4003b8 <printf@plt>
302   4004f3:   b8 00 00 00 00          mov    $0x0,%eax

如果按照这样来算是对的:
     -0xc000000 的补码形式为 0x40000000,计算方法:2 ^ 32 - 3221225472(3221225472为0xc0000000的十进制表示)
     - 128 << 20 的补码形式为 0xf8000000,计算方法:2 ^ 32 - 134217728(134217728为128<<20的十进制表示)
然后两个补码求和: 0x40000000 + 0xf8000000 = 0x1 38000000,最高位溢出不要,剩余的38000000表示的无符号整数刚好是896M

怎么理解这里的这个 -0xc0000000 - 128 << 20  ???


作者: shaohui973    时间: 2014-04-12 19:04
本帖最后由 shaohui973 于 2014-04-12 19:04 编辑

高手在哪里?指导下小弟,感激不尽。
作者: asuka2001    时间: 2014-04-13 19:00
回复 2# shaohui973


你检查下 c运算符的优先级吧。。。 ‘-’ 优先级大于 '<<'




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2