[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 壹

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

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

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

译文:

"生活就像是一台收银机,那些誓言、思想还有功绩就像是每笔交易,都被登记在册" ---- 富尔顿·约翰·施恩 (Fulton J. Sheen, 1859-1979),美国罗马天主教主教、教育家、作家

简介

在处理器的内部也有一些存储的空间叫做寄存器,不同类型处理器根据其设计结构和设计目的的不同,各自有着不同类型的寄存器。得益于距离处理器极近,与处理器联系密切,所以对于数据的移动,加减操作,读取写入要比任何其他的存储设备(比如高速缓存,内存,硬盘等) 效率更高,速度更快(由于是集成在处理器内部,造价也更高,存储空间也更小),接下来我们将要康康m68k 中的16 个通用寄存器是干什么的:

数据寄存器

m68k 拥有8 个数据寄存器,他们分别被命名为:

    d0, d1, d2, d3, d4, d5, d6, d7

数据寄存器被用来在数学层面上存储和修改数据,每个寄存器都拥有一个长字大小的存储空间:

寄存器名称 存储空间(十六进制)
d0 00 00 00 00
d1 00 00 00 00
d2 00 00 00 00
d3 00 00 00 00
d4 00 00 00 00
d5 00 00 00 00
d6 00 00 00 00
d7 00 00 00 00

让我们用之前那条指令来做例子:

    move.w     #$04F0, d0

这将会把 04F0写入寄存器d0,指令被m68k 执行后,d0中的内容将会是00 00 04 F0

当然你也可以在任何时候对这些寄存器执行字节或是长字的指令(通过指令命令后的.b.w还有.l来指定),而且大部分的指令都可以支持对寄存器的操作,我们将会在之后再详细说明

地址寄存器

m68k 也拥有8 个地址寄存器,分别称为:

    a0, a1, a2, a3, a4, a5, a6, a7

每个地址寄存器同样也包含一个长字大小的存储空间:

寄存器名称 存储空间(十六进制)
a0 00 00 00 00
a1 00 00 00 00
a2 00 00 00 00
a3 00 00 00 00
a4 00 00 00 00
a5 00 00 00 00
a6 00 00 00 00
a7 00 00 00 00

它们在使用上与数据寄存器类似,除了有一点:你不能对它们执行字节长度的指令(只有长字可以),而且有一些类型的指令 只能 工作在数据寄存器上而 不能 工作在地址寄存器上,此处不详细展开,后续会有介绍

这些地址寄存器被用来存储地址(也就是之前常说的偏移量),而且能够写入和读取地址,比如:

    movea.l    #$00000039, a0

这条指令会把长字 00000039写入a0,所以a0在指令执行后的内容是00000039,看起来和数据寄存器的用法基本一致。而现在我们的a0里面已经有一个长字的数据了,就可以根据这点做出另一种操作:

    move.b     #$44, (a0)

不知你是否留意到,这次我们把a0加了括号里变成了(a0),那么m68k 在看到这条指令的时候并不会把44放到a0里,而是会把它放到a0里面的内容所代表的地址中,比如此时a0的内容是00000039,所以这条指令执行后会把44放到内存中00000039的位置:(学习过《计算机组成原理》的同学应该知道,此方式即为寄存器间接寻址)

偏移量 0 1 2 3 4 5 6 7 8 9 A B C D E F
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000030 00 00 00 00 00 00 00 00 00 44 00 00 00 00 00 00
...

如你所见,此时的a0像是一个内存的代理

除此之外,地址寄存器还有一些其他的功能,比如"索引",比如说(假设a0里面的内容仍然是00000039):

    move.b     #$9B, $04(a0)

这次我们把目的操作数改成了$04(a0),其中$04就是索引值,这将会把a0里的内容和索引值$04相加得到一个新的偏移量作为目的操作数,即00000039 + 04 = 0000003D,所以内存中0000003D位置被修改为9B

偏移量 0 1 2 3 4 5 6 7 8 9 A B C D E F
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 9B 00 00
...

好了,休息一下,我们再继续

这里有另外一个更直观的例子:

    movea.l    #$00000010, a0
    move.b     #$20, $01(a0)
    move.b     #$40, $02(a0)
    move.b     #$F0, $0F(a0)
    move.b     #$0E, (a0)

那么,解释一下就是

  1. 00000010写入地址寄存器 a0
  2. 20写入偏移量 00000011 (00000010 + 01)
  3. 40写入偏移量 00000012 (00000010 + 02)
  4. F0写入偏移量 0000001F (00000010 + 0F)
  5. 0E写入偏移量 00000010

结果就是:

偏移量 0 1 2 3 4 5 6 7 8 9 A B C D E F
00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000010 0E 20 40 00 00 00 00 00 00 00 00 00 00 00 00 F0
00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
00000030 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
...

自增/自减

另一个功能是"自增"和"自减",来康康这个:

    movea.l    #$00000020, a0
    move.b     #$B5, (a0)+
    move.b     #$11, (a0)+

我们又把上面你所知的(a0)改成了(a0)+,括号的右边加了个+号,这,就是"自增":

  1. 00000020写入a0
  2. B5写到a0中的地址 (把B5写到内存中的00000020位置)
  3. +符号会把a0中的内容自动 +1,此时a0中的内容是00000021 (00000020 + 1)
  4. 11写到a0中的地址 (把11写到内存中的00000021位置)
  5. +符号把a0内容 +1,此时a0中是00000022 (00000021 + 1)

没错,我们刚刚对(a0)做的改动(a0)+就是一旦数据被写到对应的地址 (偏移量)之后,就把a0的内容 +1

再来康康另一个例子,跟刚才不同的是这次我们用了 move.w 而不是 move.b

    movea.l    #$00000020, a0
    move.w     #$A90E, (a0)+

  1. 00000020写入a0
  2. A90E写入到a0中存储的地址 00000020 (其中A9写入到000000200E写入到00000021)
  3. +符号会把a0中的内容自动 +2(现在a0中的内容是00000022)

为什么这次会 +2 呢,就是因为我们操作了一个长度的数据,而一个恰好是2 个字节的长度。同理,如果我们用 move.l 来类似的操作一个长字的数据,那么a0中的内容会自动 +4,因为一个长字是4 个字节

"自减"也很类似,不过是反着的:

    movea.l    #$00000020, a0
    move.b     #$2E, -(a0)

可能你注意到这个例子里,有一个-符号,但是它却在(a0)的左边而不是右边:

  1. 00000020写入a0
  2. -符号会把a0中的内容自动 -1 (现在a0中的内容是0000001F)
  3. 2E写入到0000001F

对于"自减"来说,地址寄存器总是在指令操作源操作数之前进行"自减"

好啦,本节就到这里,仍还有一些其他的"索引"方式用于地址寄存器,但目前为止留给此后的其他章节比较合适

对于自增和自减,我还未遇到诸如(a0)-或是+(a0)之类的写法,所以正如原作者所说,仅有(a0)+-(a0)的写法

目录
上一篇:[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 壹 - 基础介绍 | 3. 指令集
下一篇:[转译][马基 杰斯特(MarkeyJester) 摩托罗拉68000 入门教程] 壹 - 基础介绍 | 5. MOVE 指令

原文地址:https://www.cnblogs.com/strawhatboy/p/12291791.html