首页 > 编程知识 正文

有符号数和无符号数相加,有符号数和无符号数的范围

时间:2023-05-06 02:21:46 阅读:190830 作者:226

写在正文的前面:终于在四十多岁的时候,干自己喜欢干的事情了。博客中所有文章都是原创,转载注明!!!

专题:汇编语言中有符号数还是无符号数?

一、汇编语言在存储方面讲,有符号数和无符号数存储形式是一致的。

l  数据在内存或CPU的寄存器中都是按照有符号数的二进制补码方式存储的。

       例如(在debug中测试):

       mov ax,-9

       怎么理解这个代码?首先-9==-09H,它是16进制的(在debug中一律按照16机制存储,没有十进制,是在汇编语言中可以写十进制,编译器会给你自动处理了,在debug中不行,当然此例中也可以是十进制的,因为它们还没有差别呢)。

       -09H的二进制补码是:

       原码:1000 0000 0000 1001B       反码:1111 1111 1111 0110B

       补码(反码+1):1111 1111 1111 0111B==FFF7H

       我们在debug中查看结果:

0B04:0100 mov ax,-9

-t

AX=FFF7  BX=0000  CX=0000  DX=0000  SP=FFEE  BP=0000  SI=0000  DI=0000

DS=0B04  ES=0B04  SS=0B04  CS=0B04  IP=0103   NV UP EI PL NZ NA PO NC

       测试结果:我们发现,在存储这个方面来说,汇编都是按照二进制补码方式存储二进制数据或指令的。

l  编译器不区分是有符号数还是无符号数。

       在汇编语言的源代码中,我们可以随意设置一个数据,无论它是十六进制的还是十进制的。但是在存储层面上,它一律是按照二进制的补码方式存储的。这中间还有个编译器帮助你转换成了二进制的补码。编译器不区分是有符号数还是无符号数。

       例如,汇编源代码如下:

assume cs:code

data segment

    db -20  ;十进制表示,单字节,高字节截断了

    db 236  ;十进制表示,单字节,高字节截断了

    db 0ecH ;十六进制表示,二进制的补码

data ends

code segment

start:

        mov ax, data

        mov ds,ax

        mov ax,4c00H

        int 21H

code ends

end start

编译、连接后,debug结果:

-d ds:0

0B65:0000  EC EC EC 00 00 00 00 00-00 00 00 00 00 00 00 00   ................

    我们发现:在内存中都是以EC存储的。这个EC是?-20的补码?我们看下。

    -20原码:10010100               反码:11101011B         补码:11101100B==ECH

那么236原码:11101100B  对于正数它的补码就是源码  故它的补码:11101100B==ECH

    疑问?难道+236等于了-20?,关键在于存储的内存单元的大小,目前程序设定的是单字节存储这3个数据,它们都是一样的。

    貌似在编译器层面上,将有符号数和无符号数这二个标准统一成一个结果。也就是说编译器本身在识别完这些数字之后,会将其统一转换为补码形式,然后将这些常量放置在存储单元之中。换句话说,在编译器层面上,能够识别二种标准的。其实不然,就一种标准:有符号二进制补码。产生上述的原因是由于存储单元容量小,存储不下高位的信息了,截断了高位。

    但是对于2个字节存储这些数据:-20(FFECH)、236(00ECH)、ECH(00ECH)。这个就区分出来了。我们还发现了,对于二进制补码,最高位是1代表负数,0代表正数,这个符号位(最高位)在计算机的原码和补码中是一致的。其他的位是数据位。

 二、在汇编程序层面上,还是要区分有符号数和无符号数的。

    计算机对有符号和无符号数区分的十分清晰,因为计算机进行某些同样功能的处理时有两套指令作为后备,这就是分别为有符号和无符号数准备的。

       一个数到底是有符号数还是无符号数,计算机并不知道,这是由程序员来决定的,飞快的绿茶认为你要处理的数是有符号的,那么你就用那一套处理有符号数的指令,飞快的绿茶认为你要处理的数是无符号的,那就用处理无符号数的那一套指令。

    加减法只有一套指令,因为这一套指令同时适用于有符号和无符号。下面这些指令:mul div movzx … 是处理无符号数的,而这些:imul idiv movsx … 是处理有符号的。
    还有,在程序员在程序层面上区别是有符号数和无符号数,在底层CPU也可以通过flag寄存器的标志位来判断的有符号数和无符号数。

三、结论:

       1)在汇编语言中。数据或代码是按照二进制补码方式存储的,无论数据是有符号数还是无符号数。那是汇编语言编译器需要干的事情,自动帮你转换了。

       2)在计算机底层,我们要注意内存单元和寄存器变量所能存储的最大位数,也就是说利用补码方式存储的数据的范围;注意溢出的问题。

       3)在程序员编写指令时,要考虑有符号数和无符号数,对它们使用不同的指令区分。也就是说运算的时候,可能可以选择不同的命令来指定把要操作的数据(补码形式存在)当多有符号数或是无符号数来使用。

       4)对于CPU来说,只能通过flag的标志位来判断有符号数和无符号数的运算结果。

       5)对于是否是有符号数还是无符号数,程序员不必太纠结,在汇编语言源程序编程这个层面上,你只要按照你所期望的使用指令就行了。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。