[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 肆 - 正负 指令 | 2. 有符号 和 无符号

注意:本文经过原作者授权转译,转载请标明出处

原文地址:http://mrjester.hapisan.com/04_MC68/Sect04Part02/Index.html

条件允许建议阅读原文,网上非中文资料还是较多,当作锻炼英文岂不美哉
翻译若有不足之处欢迎批评指正

译文:

"积极正面的态度或许不能解决你所有的问题,但它却能让足够多的人的努力不会白费" ---- 赫姆奥尔布赖特 (Herm Albright),《读者文摘》(Reader's Digest),1995年6月

简介

我们知道在数学里,有一些数是负数 (-1, -2, -3...),在这一节让我们来康康有符号数和无符号数,以及它们在程序设计中是怎样模拟 (假装) 负数的

无符号数

现在,你一定同意一个字节数据的最小值是00,而FF是最大值。对于来说0000是最小值,而FFFF是最大值。对于长字来说00000000是最小值,而FFFFFFFF是最大值

我觉得你没什么异议

这些,就是我们所说的无符号数 (unsigned),无符号数是从00开始一直到FF的正数

有符号数

然而,总是会有你想要使用负数的情况,这个时候,我们就需要引入有符号数 (signed) 的概念

当一个字节的数据被当成有符号数时,从007F都是正数,而从80FF都是负数!(学习过《计算机组成原理》的同学应该比较清楚):

    无符号数

最小值 最大值
00 01 02 03 04 05 06 07... ... F8 F9 FA FB FC FD FE FF

    Signed

最小值 最大值
80 81 82 83... ...FC FD FE FF 00 01 02 03 04... ...7C 7D 7E 7F

如你所见对于有符号数来说,80FF红色的,表示负数

    ...
    03    =    +3
    02    =    +2
    01    =    +1
    00    =     0
    FF    =    -1
    FE    =    -2
    FD    =    -3
    ...

这就是传说中的二进制补码,就是用MSB (最高有效位) 作为符号位,当其为1时表示负数,比如:

    80    =    1000 0000

所有的从80FF的数的MSB (最高有效位) 都是1,对于正数来说,这一位是0

对于长字也是一样:

    8000    =    1000 0000 0000 0000

    80000000    =    1000 0000 0000 0000 0000 0000 0000 0000

注意,这里不要把字节长字弄混在一起了:

比如字节FC-4,但是如果你用的长度去读取FC,读成00FC,那么这个数就不再是负数了,它就会变成了一个正数,因为它在00007FFF之间,如果你想把它以的长度读成-4,那么就需要对其进行长度扩展成FFFC,对于长字也是一样,你要把它扩展成FFFFFFFC

正负转换

需要特别说明的是,如果只是修改MSB的话,并不会把一个数从正数转换成它的相反数,反之亦然。比如正数04用二进制表示为0000 0100,如果把MSB修改一下变成1000 0100,也就是十六进制的84,但是84并不是-4,事实上它是-7C

负数从FF (-1)开始,然后逐步做减一操作:FE (-2),FD (-3),FC (-4)...

当然也有比较简单的方法来做数字的正负转换,也就是传说中的取反+1操作,取反也就是类似于not指令,把所有的做翻转,之后再 +1 就可以了,拿04来举例,先把它取反:

        0000 0100
        |||| ||||
        vvvv vvvv
        1111 1011

我们得到了FB (1111 1011),然后再 +1 得到FC (-4)。是不是很简单,同样的对于负数转换成正数也是一样的规则。在cpu 内部执行NEG指令时,做的就是这样的操作 (我们会在下一节有些涉及)

额外的情报

你接下来可能会问了:"我怎么区分对待一个数为正数还是负数呢",答案很简单,但是解释起来有点复杂,所以请忍耐一下

m68k 有一个叫做 "状态寄存器" (CCR, Conditional Code Register) 的东西,每当一条指令被处理的时候,一些必要的信息都会被保存到这个CCR里,这些信息包括:

  • 运算结果是不是00 (Z 标记)
  • 运算结果是正的还是负的 (N 标记),仅对有符号数
  • 运算结果是否溢出 (V 标记),仅对有符号数
  • 运算结果是否溢出 (C/X 标记),仅对无符号数

如你所见,有符号数和无符号数的一些信息都被存在CCR里了,所以大部分情况下,数字会被同时当作有符号数和无符号数

还有一些我们之后会介绍的指令,它们会去读取CCR里的一些标记然后根据这些标记的值来做出不同的动作,那样的话,你就可以完全决定是把数当成有符号数还是无符号数了

重要: 上面关于CCR的介绍非常基础,在合适的时候我们会公开更多的情报,这里做些简单的解释可以让你明白数的有符号和无符号的表示。所以如果你现在不太清楚CCR也完全没关系

目录
上一篇:[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 肆 - 正负 指令 | 1. 有效位
下一篇:[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 肆 - 正负 指令 | 3. NEG 指令

posted @ 2020-02-25 10:28  草帽过客  阅读(478)  评论(0编辑  收藏  举报