常见单位有:
示例:
#include <stdio.h>
#include <windows.h>
int main(void)
{
int a = 0xAFFFFFF2B;
printf("%x", &a);
return 0;
}
int
整型,存储占用4字节,可存储8位十六进制、32位二进制。
赋值0xAFFFFFF2B
,9位十六进制,即36位二进制,超出int
存储范围。
查看内存窗口,0x2F1892
地址的数据为2B FF FF FF
:
A
没有出现,默认被抛弃了。
0x
表示十六进制,0b
表示二进制,0
表示八进制,十进制不需要附加符号。
示例:
#include <stdio.h>
int main() {
int a = 0x1AFFFFFF;
printf("无符号:%u\n", a);
printf("有符号:%d\n", a);
return 0;
}
输出为:
无符号:452984831
有符号:452984831
0x1AFFFFFF
转为二进制就是0001 1010 1111 1111 1111 1111 1111 1111
,符号位是0
,表示正数。对于正数而言,有无符号数是一致的。
将符号位换为1
:
#include <stdio.h>
int main() {
int a = 0xFAFFFFFF;
printf("无符号:%u\n", a);
printf("有符号:%d\n", a);
return 0;
}
输出为:
无符号:4211081215
有符号:-83886081
0xFAFFFFFF
转为二进制就是1111 1010 1111 1111 1111 1111 1111 1111
,符号位是1
,表示负数。
正数在内存中不管按照原码、反码还是补码存储都是正确的。
正、负数的原码差异在于最高位(符号位)是0
还是1
。
正数无需变动。负数符号位保持不变,其余位置取反。如1000 1011
的反码为1111 0100
。
正数无需变动,负数反码+1。如1000 1011
的补码为1111 0101
。
示例代码:
#include <stdio.h>
int main() {
char a = -1;
printf("%x\n", &a);
return 0;
}
某次执行结果为:
10ffd1b
根据这个地址就可以找到-1
在内存中的存储状态:
可以发现-1
在内存中为FF
,char
是1字节(8 bits)。
-1
原码:二进制1000 0001
,即十六进制81
。
-1
反码:二进制1111 1110
,即十六进制FE
。
-1
补码:二进制1111 1111
,即十六进制FF
。
负数在内存中的存储方式是补码形式。
举例(0x95A55555
):
#include <stdio.h>
int main() {
int a = 0x95A55555;
printf("无符号:%u\n", a);
printf("有符号:%d\n", a);
return 0;
}
输出为:
无符号:2510640469
有符号:-1784326827
二进制 | 1001 0101 1010 0101 0101 0101 0101 0101 |
补码 | 1110 1010 0101 1010 1010 1010 1010 1011 |
数值 | (0)110 1010 0101 1010 1010 1010 1010 1011 |
十六进制 | ?6A5A AAAB? |
最终(十进制) | -1784326827 |
and
&
or
|
xor
^
not
~
shl
<<
二进制左移若干位,高位丢弃,低位补0。
shr/sar
>>
二进制右移若干位,低位丢弃。对于无符号数强制高位补0,对于有符号数续补符号位。
C语言中如果需要补符号位,使用int
、long
这样普通的声明即可,不加上unsigned
。
原文:https://www.cnblogs.com/4thrun/p/ASM_1.html