[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 贰 - 基本指令 | 2. SUB 指令(减)

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

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

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

译文:

"如果人们不肯相信数学很简单的话,他们可能只是没意识到生活有多难" ---- 冯 诺依曼 (John Louis von Neumann, 1903-1957),计算机之父

简介

SUB () - 二进制减法

这条指令能把目的操作数减去源操作数,结果再放回到目的操作数中,而源操作数保持不变

例子

这显然是add指令的反操作,比如下面这个例子:

    subi.b     #$10, d0

这会把字节10从数据寄存器d0中减去:

  • 如果d0里原本是00000010,那么指令执行后d0里的内容会变成00000000
  • 如果d0里原本是0000002E,那么指令执行后d0里的内容会变成0000001E
  • 如果d0里原本是000000E4,那么指令执行后d0里的内容会变成000000D4
  • 如果d0里原本是00000008,那么指令执行后d0里的内容会变成000000F8

当然别忘了,我们只是在减一个字节,所以:

  • 如果d0里原本是00001014,那么指令执行后d0里的内容会变成00001004
  • 如果d0里原本是222222FC,那么指令执行后d0里的内容会变成222222EC
  • 如果d0里原本是33333301,那么指令执行后d0里的内容会变成333333F1

上面所有的指令都遵循这么一个规则,就是只有最右边那个字节被修改了

在来康康一个用的例子:

    subi.w     #$0200, d0

这会把0200从数据寄存器d0中减掉:

  • 如果d0里原本是00000500,那么指令执行后d0里的内容会变成00000300
  • 如果d0里原本是00004B20,那么指令执行后d0里的内容会变成00004920
  • 如果d0里原本是4444310F,那么指令执行后d0里的内容会变成44442F0F

当然同样的,只有最右边的会受到影响

别的例子

你可以从寄存器里减掉另一个寄存器的内容:

    sub.l      d0, d1

这条指令会把d1里的内容减掉d0里的内容:

  • 如果d0里原本是010000F0d1里原本是02000100,那么指令执行后d1里的内容会变成01000010

你也可以把内存中的数据做减法:

    sub.w      d0, $0000102E

这会把d0中的一个复制出来,然后用内存中地址为$0000102E位置的数据减去它,再放回$0000102E中。如果d0中的内容是09920022,内存中$0000102E$0000102F位置的字节分别是002E,那么002E - 0022 = 000C00 0C就会被写入到内存中$0000102E$0000102F的位置:

偏移量 0 1 2 3 4 5 6 7 8 9 A B C D E F
...
00001000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00001010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00001020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0C
00001030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
...

你也可以把寄存器中的数据减去内存中的数据:

    sub.b      $00001040, d0

如果d0中的内容是00121080,内存中的数据是:

偏移量 0 1 2 3 4 5 6 7 8 9 A B C D E F
...
00001030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00001040 70 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00001050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00001060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
...

70会被从内存中复制出来,然后由d0中的字节80减去,指令执行后d0的内容会变成00121010

和加法指令add一样,你也不能从一个内存地址减去另一个内存地址的数据:

    sub.b      $00000120, $00000124     ?

不过这里同样也有类似的解决方法:

    move.b     $00000120, d0
    sub.b      d0, $00000124

如你所见,我们先把内存中00000120中的数据放到一个数据寄存器里,然后再从内存的00000124位置中减去这个数据寄存器中的内容

同样的你也可以使用地址寄存器来做寄存器间接寻址

    sub.w      d1, $72(a0)
    sub.l      $40(a0), d4
    sub.w      d5, (a1)
    subi.b     #$98, (a0)+
    sub.w      a1, d0

然而你也一样不能通过地址寄存器的间接寻址从内存中去减内存的数据:

    sub.w      (a0), (a1)         ?
    sub.l      (a0)+, $10($a2)    ?
    sub.w      $9E(a4), -(a3)     ?
    sub.b      $10(a0), $10(a6)   ?

减 立即数

跟加法指令一样,如果源操作数立即数,你必须使用subi指令,而不是sub指令 (其中i表示立即数)

    subi.b     #$20, d0

同样的汇编程序在汇编代码的时候会自动把需要用到subi的地方的sub修改为正确的写法

目录
上一篇:[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 贰 - 基本指令 | 1. ADD 指令(加)
下一篇:[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 贰 - 基本指令 | 3. SWAP 指令

[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 贰 - 基本指令 | 2. SUB 指令(减)

上一篇:Android头像更换之详细操作


下一篇:[Android]动态改变shape背景颜色