- 论坛徽章:
- 0
|
在看补码的时候遇到一个古怪的问题,似乎编译器对十进制常量汇编的时候,会做一个转换,但是其它进制不会:
- test.c
- #include <stdio.h>
- int main()
- {
- char a = 0b00000000;
- char b = 0b10000001;
- printf("a: %d, b:%d\n", a, b);
- return 0;
- }
复制代码 #make test
#./test
a: 0, b:-127
为什么b不是-1而是-127呢,看来是用二进制表示的时候,汇编器将0b10000001直接读入了,而printf读出的时候,
CPU内部做了转换,也即10000001 取反11111110再加1求得11111111,也即-127
查看生成的反汇编代码为:
80483cd: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483d2: c6 44 24 1e 81 movb $0x81,0x1e(%esp)
第一句将0x0放入堆栈esp+0x1f处,第二句将0x81放入堆栈esp+0x1e处,0x81就是0b10000001。
看来当使用二进制给出初始值的时候,汇编器忠实于原数值。
再看下面程序:
#include <stdio.h>
int main()
{
char a = 0b00000000;
char b = -1;
printf("a: %d, b:%d\n", a, b);
return 0;
}
#./test
a: 0, b:-1
查看生成的汇编代码为:
80483cd: c6 44 24 1f 00 movb $0x0,0x1f(%esp)
80483d2: c6 44 24 1e ff movb $0xff,0x1e(%esp)
第一句将0x0放入堆栈esp+0x1f处,第二句将0xff放入堆栈esp+0x1e处,0xff就是-1的补码。
看来当使用十进制给出初始值的时候,汇编器将翻译原数值为补码到机器指令。
假如我们使用十六进制呢,char b = 0x81; 打印结果与二进制给出的结果是一致的,另外测试8进制是结果也为-127。
难道只有十进制的时候,编译器会忠实于赋予的值? 为什么要这样处理? 请不吝指点! |
|