有符号数和无符号数探讨
时间:2010-05-13 来源:wuliqingyt
C语言 | 编译后生产的汇编语言 |
…… char x; unsigned char y; int z; x = 3; y = 236; z = x*y; …… | …… _x$ = -4 _y$ = -8 _z$ = -12 …… mov BYTE PTR _x$[ebp], 3 mov BYTE PTR _y$[ebp], 236 movsx eax, BYTE PTR _x$[ebp] mov ecx, DWORD PTR _y$[ebp] and ecx, 255 imul eax, ecx mov DWORD PTR _z$[ebp], eax …… |
我们看到,在赋值的时候(绿色部分),汇编后与本文第一条论述相同,是否有符号把握全在自己,c比汇编做的更好这一点没有得到体 现,这也可以理解,因为c最终要被编译成汇编,汇编没有在变量声明时区分有无符号这一功能,自然,c也没有办法。但既然c提供了signed和 unsigned声明,汇编后,肯定有代码体现这一点,表格里的红色部分就是。对有符号数x他进行了符号扩展,对无符号y进行了零扩展。这里为了举例的方 便,进行了有符号数和无符号数的混合运算,实际编程中要避免这种情况。 (完) 附录: 1.计算机对有符号整数的表示只采取一套编码方式,不存在正数用原码,负数用补码这用两套编码之说,大多数计算机内部的有符号整数都是用补码,就是说无论正负,这个计算机内部只用补码来编码!!!只不过正数和0的补码跟他原码在形式上相同,负数的补码在形式上与其绝对值的原码取反加一相同。 2. 两套乘法指令结果例程: ;; 程序存储为 x.s extern printf global main section .data str1: db "%x",0x0d,0x0a,0 n: db 0x02 section .text main: xor eax,eax mov al, 0xec mul byte [n] ;有符号乘法指令为: imul push eax push str1 call printf add esp,byte 4 ret 编译步骤: 1. nasm -felf x.s 2. gcc x.o ubuntu7.04 下用nasm和gcc编译通过。结果符合文章所述。 traceback:http://hi.baidu.com/liu%5Fbin0101/blog/item/0b931880270dafd19023d94e.html 为什么c语言中short的表示范围是-32768~32767 2009-09-30 14:42
这得从二进制的原码说起:
结论:有符号数和无符号数在计算机中都按照有符号数补码形式存储,但处理指令有两套,计算机不知道用哪套,决定者还是我们! |