首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

大小端与移位(3)

大小端与移位(3)

如果代码这样写
short a
char b
b = (char)a;
b的值和大小端是没有关系的
因为向下的类型转换时,保留的是a值的低字节部分,而不是内存中数据的低地址字节部分
对于小端模式 :向下强制转换数据时,计算机不需要调整内存中的数据内容,保留a的低字节就行了
对于大端模式:向下转换后,a的低字节被保留,并且该被保留的低字节数据在内存中还要被放到合适的位置

如果是
a=b ; 这是自动向上的类型转换,向上不需要强转,数据高字节自动补0


关于移位
在x86平台, vc6中 ,  有  a=i<<n若i是一个变量,则
移位数是n%=32,
若移位n=33, 就是移1位
若移位n=32, 就是移0位
也就是取n的低5位作为有效移位值

若i是立即数, n不会执行 n%=32
例如a=(1<<33)   , a=0




在keil4中的c51,左移位数最多是15位,大于15就结果为0
u16 a =1;
a|=(1<<15)         a=0x8001
a|=(1<<16)         a=0x0001 即 1<<(16+x)结果为0 ,也就是说移位超过15就结果是0

u32 a=1;
a|=(1<<14)         a=0x00004001 这个也正常
a|=(1<<16)         这个结果是1 因为1<<16=0

a|=(1<<15)         a=0xffff8001
当左移后,第15位为1时,就会出现这种情况,a的高16位都是1

在mdk中没有这种情况,而且移位也没有vc中取余的情况,移位数大于31时结果为0


============================================================
再来看一下vc6中的右移
c代码1
unsigned long a = 0x80000000;
a>>=33;

反汇编代码
10: unsigned long a = 0x80000000;
004010B8 mov dword ptr [ebp-4],80000000h
11: a>>=33;
004010C6 mov eax,dword ptr [ebp-4]
004010C9 sar eax,21h //无符号右移,也称逻辑右移,同java中的>>>
004010CC mov dword ptr [ebp-4],eax
a = 0x40000000 ,即0x80000000 sar 1


c代码2
long a = -2147483648; //32位long的最小值
a>>=33;

反汇编代码
11: long a = -2147483648;
004010B8 mov dword ptr [ebp-4],80000000h
12: a>>=33;
004010C6 mov eax,dword ptr [ebp-4]
004010C9 shr eax,21h //有符号移位,也称算术右移,同java中的>>
004010CC mov dword ptr [ebp-4],eax
a=-1073741824 ,或者说a=0xc0000000,即0x80000000 shr 1
结果表明
无符号类型数右移,高位补0,用的是sar指令
有符号类型数右移,高位补符号,用的是shr指令
移位数也是低5位有效,a=33时,相当于右移1位

在keil4中
无符号类型数右移,高位补0,有符号类型数右移,高位补符号,这一点上是一样的
右移位个数没有限制,不会对右移个数进行取余
继承事业,薪火相传
返回列表