常见单位有:
示例:
#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