又见右移位,右移位

本文通过对比两个函数FooA和FooB中使用无符号char与有符号char类型的变量进行右移位操作的不同结果,深入探讨了逻辑右移(shr)与算术右移(sar)的区别。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

昨天有一篇关于右移位研究的文章, 网友提出了正确的观点,真的很感谢他---Tcice.为了落实认真负责的精神,今天晚上特别再对此做个研究.下面是我的研究对象:
void FooA()
{
     unsigned 
char i = 160;
     
long c = i >> 1;
     printf(
"%d",c);   
}

void FooB()
{
     
char i = 160;
     
long c = i >> 1;
     printf(
"%d",c);   
}

int main ()
{
     FooA();
     FooB();
     
return 0;
}

可以看到,那两个子函数只有一个地方不同,就是关于局部变量i,FooA是无符号char,FooB则是有符号char.现在编译连接,
gcc -g main.c -o main.exe
加上了参数-g,是为了用gdb调试.
进入gdb,加载main.exe后,我对FooA和FooB分别进行了反汇编,下面是结果:
(gdb) disassemble  FooA
Dump of assembler code for function FooA:
0x4012d3 <FooA>:        push   %ebp
0x4012d4 <FooA+1>:      mov    %esp,%ebp
0x4012d6 <FooA+3>:      sub    $0x8,%esp
0x4012d9 <FooA+6>:      movb   $0xa0,0xffffffff(%ebp)
0x4012dd <FooA+10>:     mov    0xffffffff(%ebp),%al
0x4012e0 <FooA+13>:     shr    %al
0x4012e2 <FooA+15>:     and    $0xff,%eax
0x4012e7 <FooA+20>:     mov    %eax,0xfffffff8(%ebp)
0x4012ea <FooA+23>:     sub    $0x8,%esp
0x4012ed <FooA+26>:     pushl  0xfffffff8(%ebp)
0x4012f0 <FooA+29>:     push   $0x4012d0
0x4012f5 <FooA+34>:     call   0x401840 <printf>
0x4012fa <FooA+39>:     add    $0x10,%esp
0x4012fd <FooA+42>:     leave
0x4012fe <FooA+43>:     ret
End of assembler dump.
(gdb) disassemble  FooB
Dump of assembler code for function FooB:
0x4012ff <FooB>:        push   %ebp
0x401300 <FooB+1>:      mov    %esp,%ebp
0x401302 <FooB+3>:      sub    $0x8,%esp
0x401305 <FooB+6>:      movb   $0xa0,0xffffffff(%ebp)
0x401309 <FooB+10>:     mov    0xffffffff(%ebp),%al
0x40130c <FooB+13>:     sar    %al
0x40130e <FooB+15>:     movsbl %al,%eax
0x401311 <FooB+18>:     mov    %eax,0xfffffff8(%ebp)
0x401314 <FooB+21>:     sub    $0x8,%esp
0x401317 <FooB+24>:     pushl  0xfffffff8(%ebp)
0x40131a <FooB+27>:     push   $0x4012d0
0x40131f <FooB+32>:     call   0x401840 <printf>
0x401324 <FooB+37>:     add    $0x10,%esp
0x401327 <FooB+40>:     leave
0x401328 <FooB+41>:     ret
End of assembler dump.
在反汇编里,FooA中有这么一行
0x4012e0 <FooA+13>:     shr    %al
shr也就是对al进行逻辑右移
在相同的地方,FooB却是这样的;:
0x40130c <FooB+13>:     sar    %al
sar就是对al进行算术右移.....
原来如此.....
我知道了.....
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值