21 123
发新话题
打印

【讨论】-1 左移 32 位结果还是 -1?

【讨论】-1 左移 32 位结果还是 -1?

复制内容到剪贴板
代码:
[color=blue]-(dearvoid@LinuxEden:tty3)-(~/tmp)-
[21370 0] #[/color] cat foo.c
#include <stdio.h>

int main()
{
    int n = 32;

    printf("%d\n", -1 << n);

    return 0;
}
[color=blue]-(dearvoid@LinuxEden:tty3)-(~/tmp)-
[21370 0] #[/color] gcc -o foo foo.c
[color=blue]-(dearvoid@LinuxEden:tty3)-(~/tmp)-
[21370 0] #[/color] ./foo
-1
[color=blue]-(dearvoid@LinuxEden:tty3)-(~/tmp)-
[21370 0] #[/color] gcc --version
gcc (GCC) 4.0.3 (Ubuntu 4.0.3-1ubuntu5)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[color=blue]-(dearvoid@LinuxEden:tty3)-(~/tmp)-
[21370 0] #[/color] o
      
'
◆ 发帖时请【突出主题】, 以便您的问题能够及时得到回复
◆ 发帖时请将您的【代码】或者【脚本】写在 [code] 和 [/code] 中间

TOP

int n=-1<<32;! m6 x8 c/ N8 \/ Z$ p) `! o
printf("%d\n", n);
/ t, k  d2 w3 E- R3 v7 |  {0 \……2 J; T$ R6 @; a
貌似只能这样理解了      
上帝说,有问题,找GOOGLE 写程序是很神圣的事情!同样只是装系统,卖菜的大娘会的事情不见得就跟卖菜一样了。

TOP

有些牵强, 说服力不够      
'
◆ 发帖时请【突出主题】, 以便您的问题能够及时得到回复
◆ 发帖时请将您的【代码】或者【脚本】写在 [code] 和 [/code] 中间

TOP

32 位的机器上, 左移或者右移 32 bit 编译器将会做取模运算,然后再次移动, 所以左移和右移 32bit 是没有意义的...      
-----------------------------------------
http://www.darkspy.org/blog

自大的人把宗教当迷信,无知的人把迷信当宗教

TOP

ANSI C99 6.5.7 Bitwise shift operators:
0 j5 g# ~) w4 X4 S% q' x3 D[INDENT]If the value of the right operand is negative or is [B]greater than or equal to[/B] the width of the promoted left operand, the [B]behavior is undefined[/B].[/INDENT]      
'
◆ 发帖时请【突出主题】, 以便您的问题能够及时得到回复
◆ 发帖时请将您的【代码】或者【脚本】写在 [code] 和 [/code] 中间

TOP

很诡异的是用汇编打出来的,如果用printf("%d\n", -1 << 32)的话,直接就是扔了个0过去,而用printf("%d\n", -1 << n)的话,确实是shl过了的……      
上帝说,有问题,找GOOGLE 写程序是很神圣的事情!同样只是装系统,卖菜的大娘会的事情不见得就跟卖菜一样了。

TOP

-1 << 32 是个常数, 是在编译期间就计算出结果的, -1 << n 就是 run-time 的事情了      
'
◆ 发帖时请【突出主题】, 以便您的问题能够及时得到回复
◆ 发帖时请将您的【代码】或者【脚本】写在 [code] 和 [/code] 中间

TOP

[QUOTE=DarkSpy]32 位的机器上, 左移或者右移 32 bit 编译器将会做取模运算[/COLOR],然后再次移动, 所以左移和右移 32bit 是没有意义的...[/QUOTE]; H" Y! r- x( N3 e8 K/ b
按照 flag 说的汇编代码来看, 好像不是编译器取摸的, 应该是硬件的指令系统的行为      
'
◆ 发帖时请【突出主题】, 以便您的问题能够及时得到回复
◆ 发帖时请将您的【代码】或者【脚本】写在 [code] 和 [/code] 中间

TOP

复制内容到剪贴板
代码:
[color=blue]-(dearvoid@LinuxEden:tty3)-(~/tmp)-
[21369 0] #[/color] cat foo.c

void foo(void)
{
    int n = 123;
    n = -1 << n;
}
[color=blue]-(dearvoid@LinuxEden:tty3)-(~/tmp)-
[21369 0] #[/color] gcc -S foo.c
[color=blue]-(dearvoid@LinuxEden:tty3)-(~/tmp)-
[21369 0] #[/color] cat foo.s
        .file   "foo.c"
        .text
.globl foo
        .type   foo, @function
foo:
        pushl   %ebp
        movl    %esp, %ebp
        subl    $16, %esp
        movl    $123, -4(%ebp)
        [COLOR=Red]movl    -4(%ebp), %ecx
        movl    $-1, %eax
        sall    %cl, %eax[/COLOR]
        movl    %eax, -4(%ebp)
        leave
        ret
        .size   foo, .-foo
        .ident  "GCC: (GNU) 4.0.3 (Ubuntu 4.0.3-1ubuntu5)"
        .section        .note.GNU-stack,"",@progbits
[color=blue]-(dearvoid@LinuxEden:tty3)-(~/tmp)-
[21369 0] #[/color] o
      
'
◆ 发帖时请【突出主题】, 以便您的问题能够及时得到回复
◆ 发帖时请将您的【代码】或者【脚本】写在 [code] 和 [/code] 中间

TOP

SALL  cl,  eax  ! b5 a, f' c( [3 K, N1 e
: M' H" ]: K. c- p2 u
这个SALL指令似乎有个“怪癖”,就是在它执行前,它先把cl的内容用字长去一次模,比如8086字长16位,就对16取模,386+字长32位,就对32取模。
4 l, |: \( w" N! U+ ^5 G/ e8 |. s4 n9 d8 |/ G' U. B& d, _) E2 i6 t
搜出来的……莫非就是DarkSpy说的取模?      
上帝说,有问题,找GOOGLE 写程序是很神圣的事情!同样只是装系统,卖菜的大娘会的事情不见得就跟卖菜一样了。

TOP

 21 123
发新话题