跳转到内容

68000 汇编/寻址模式

来自维基教科书,开放的书籍,开放的世界

寻址模式

[编辑 | 编辑源代码]

n 是一个介于 0 到 7 之间的数字,表示要使用的哪个寄存器。

数据寄存器立即寻址

[编辑 | 编辑源代码]

汇编语法

  • Dn

直接操作数据寄存器的内容。例如

MOVE.L D1,D0

将 D1 的内容复制到 D0。执行指令时,两个寄存器都将包含相同的信息。在移动字节或字时,寄存器的上半部分将保持不变。

              ;lets assume
              ;D0=FFFFFFFF D1=01234567
 MOVE.B D1,D0 ;copies a Byte from source
              ;D0=FFFFFF67 D1=01234567
....
              ;lets assume
              ;D0=FFFFFFFF D1=01234567
 MOVE.W D1,D0 ;copies a Word from source
              ;D0=FFFF4567 D1=01234567

地址寄存器立即寻址

[编辑 | 编辑源代码]

汇编语法

  • An

直接操作地址寄存器的内容。 例如

MOVE.L A1,D0

将整个 A1 复制到 D0。执行指令后,两个寄存器都包含相同的信息。在使用地址寄存器传输时,必须使用字或长字。当字传输到地址寄存器时,位 15(符号位)将被复制到整个上半字(位 16-31)。如果不是这样,负数会变成正数。

              ;lets assume
              ;D0=FFFFFFFF A1=01234567
 MOVE.W A1,D0 ;copies a Word from source
              ;D0=FFFF4567 A1=01234567
....
              ;lets assume
              ;D0=01234567 A1=FFFFFFFF
 MOVE.W D0,A1 ;copies a Word from source
              ;D0=01234567 A1=00004567
              ; sign to A1, changed
....
              ;lets assume
              ;D0=0000FFFF A1=00000000
 MOVE.W D0,A1 ;copies a Word from source
              ;D0=0000FFFF A1=FFFFFFFF
              ; sign to A1, changed

间接寻址

[编辑 | 编辑源代码]

汇编语法

  • (An)

操作 An 指向的内存位置。例如

lea $1234,A1
move.w D0,(A1)

将 D0 的前 16 位移动到从 $1234 开始的字。另一个例子

MOVE.L (A0),D0

复制从 A0 中存储的地址位置开始的长字(你说 A0 指向长字)。如果引用一个字或长字,地址寄存器中的地址必须是偶数。小心这一点!!!

                ;lets assume
                ;D0=FFFFFFFF A1=00001000
                ;mem.addr. $1000=01234567
 MOVE.L (A1),D0 ;copies Long word starting at memory address stored in A1, to D0
                ;D0=01234567 A1=00001000
                ;mem.addr. $1000=01234567

后递增间接寻址

[编辑 | 编辑源代码]

汇编语法

  • (An)+

与间接寻址相同,但在执行指令后,An 将增加操作的大小。唯一的例外是对 A7 的字节操作 - 该寄存器必须指向偶数地址,因此它始终至少增加 2。例如

MOVE.L (A1)+,D0

将 A1 指向的长字复制到 D0,并将 A1 增加 4(因为是长字)。

                 ;lets assume
                 ;D0=FFFFFFFF A1=00001000
                 ;mem.addr. $1000=01234567
 MOVE.L (A1)+,D0 ;copies the Long word starting at address stored in A1, to D0
                 ;then increment A1 by 4
                 ;D0=01234567 A1=00001004
                 ;mem.addr. $1000=01234567

前递减间接寻址

[编辑 | 编辑源代码]

汇编语法

  • -(An)

与间接寻址相同,但在执行指令之前,An 将减少操作的大小。唯一的例外是对 A7 的字节操作 - 该寄存器必须指向偶数地址,因此它始终至少减少 2。请注意,没有后递减或前递增寻址模式。例如

MOVE.L -(A0),D2

首先将 A0 减少 4(操作数的大小),然后将 A0 中存储的地址开始的长字复制到 D2。

                 ;lets assume
                 ;D0=FFFFFFFF A1=000010A8
                 ;mem.addr. $10A4=01234567
 MOVE.L -(A1),D0 ;first decrements A1 by 4, A1=000010A4
                 ;then copies the Long word starting at address stored in A1, to D0
                 ;D0=01234567
                 ;mem.addr. $10A4=01234567

带位移量间接寻址

[编辑 | 编辑源代码]

汇编语法

  • x(An)
  • (x)(An)
  • (x,An)

操作 x + An 指向的位置,其中 x 是一个 16 位立即值。所有列出的语法都是等效的,但一些汇编器不会接受所有语法。

带索引间接寻址

[编辑 | 编辑源代码]

汇编语法

  • x(An,Dn.W)
  • x(An,Dn.W*scale)
  • x(An,Dn.L)
  • x(An,Dn.L*scale)
  • x(An,An.W)
  • x(An,An.W*scale)
  • x(An,An.L)
  • x(An,An.L*scale)
  • (x)(An,Dn.W)
  • (x)(An,Dn.W*scale)
  • (x)(An,Dn.L)
  • (x)(An,Dn.L*scale)
  • (x)(An,An.W)
  • (x)(An,An.W*scale)
  • (x)(An,An.L)
  • (x)(An,An.L*scale)
  • (x,An,Dn.W)
  • (x,An,Dn.W*scale)
  • (x,An,Dn.L)
  • (x,An,Dn.L*scale)
  • (x,An,An.W)
  • (x,An,An.W*scale)
  • (x,An,An.L)
  • (x,An,An.L*scale)

与上面相同,但另一个寄存器也将被添加。比例可以是 1、2、4 或 8。并非所有设备都支持比例。并非所有汇编器都接受所有列出的语法。

绝对近寻址

[编辑 | 编辑源代码]

汇编语法

  • (xyz).W
  • xyz.W

操作由汇编器符号扩展的 xyz 等字母指向的位置。你可以用或不用括号写这个,大多数汇编器都可以接受这两种写法。你选择哪一种很大程度上是个人喜好,但大多数人发现 (xyz).W 更易读。

绝对远寻址

[编辑 | 编辑源代码]

汇编语法

  • (xyz).L
  • xyz.L

操作由汇编器符号扩展的 xyz 等字母指向的位置。一些指令只接受近或远绝对地址中的一个,因此存在这种区别。与绝对近寻址类似,你可以根据自己的意愿包含括号。

程序计数器间接带位移量

[编辑 | 编辑源代码]

汇编语法

  • x(PC)
  • (x)(PC)
  • (x,PC)

操作 x + PC 的内存值,其中 x 是一个 16 位立即值。请注意,PC 是存储 x 的扩展字的地址(紧接在指令字之后)。所有语法都是等效的,但一些汇编器不会接受所有语法。

程序计数器间接带索引

[编辑 | 编辑源代码]

汇编语法

  • x(PC,Dn.W)
  • x(PC,Dn.W*scale)
  • x(PC,Dn.L)
  • x(PC,Dn.L*scale)
  • x(PC,An.W)
  • x(PC,An.W*scale)
  • x(PC,An.L)
  • x(PC,An.L*scale)
  • (x)(PC,Dn.W)
  • (x)(PC,Dn.W*scale)
  • (x)(PC,Dn.L)
  • (x)(PC,Dn.L*scale)
  • (x)(PC,An.W)
  • (x)(PC,An.W*scale)
  • (x)(PC,An.L)
  • (x)(PC,An.L*scale)
  • (x,PC,Dn.W)
  • (x,PC,Dn.W*scale)
  • (x,PC,Dn.L)
  • (x,PC,Dn.L*scale)
  • (x,PC,An.W)
  • (x,PC,An.W*scale)
  • (x,PC,An.L)
  • (x,PC,An.L*scale)

类似于 PC 带位移,但还会添加另一个寄存器。比例可以是 1、2、4 或 8。并非所有设备都支持比例。某些汇编器不接受某些语法。

内存间接寻址

[编辑 | 编辑源代码]

汇编语法

  • ([bd,An],od)
  • ([bd,An],An.W*scale,od)
  • ([bd,An],An.L*scale,od)
  • ([bd,An],Dn.W*scale,od)
  • ([bd,An],Dn.L*scale,od)
  • ([bd,An,An.W*scale],od)
  • ([bd,An,An.L*scale],od)
  • ([bd,An,Dn.W*scale],od)
  • ([bd,An,Dn.L*scale],od)
  • ([bd,PC],od)
  • ([bd,PC],An.W*scale,od)
  • ([bd,PC],An.L*scale,od)
  • ([bd,PC],Dn.W*scale,od)
  • ([bd,PC],Dn.L*scale,od)
  • ([bd,PC,An.W*scale],od)
  • ([bd,PC,An.L*scale],od)
  • ([bd,PC,Dn.W*scale],od)
  • ([bd,PC,Dn.L*scale],od)

这些寻址模式执行两次内存访问 - 首先读取到地址表中,其次是实际读取或写入。并非所有设备都支持。在内存间接预索引模式下,CPU 将首先读取 bd+An+Rn*scale,然后添加 od,并将结果值用作最终读取或写入的地址。在内存间接后索引模式下,CPU 将首先读取 bd+An,然后添加 Rn*scale+od,并将结果值用作最终读取或写入的地址。

立即寻址

[编辑 | 编辑源代码]

汇编语法

  • #xyz

对 xyz 进行操作。

状态寄存器寻址

[编辑 | 编辑源代码]

汇编语法

  • SR
  • CCR

SR 是整个状态寄存器,包括系统字节。CCR 只是标志位。除此之外,我不知道它如何工作。SR 仅在监控模式下可用。

唯一允许使用此寻址模式的指令是:MOVE、ANDI(与立即)、EORI(异或立即)和 ORI(或立即),称为:MOVE 到/从 CCR、MOVE 到/从 SR、ANDI 到 CCR、ORI 到 CCR、EORI 到 CCR、ANDI 到 SR、ORI 到 SR、EORI 到 SR。

           ;Example ORI to CCR
           ;lets assume CCR=$00
ORI #5,CCR ;sets both the carryflag (C) and the zeroflag (Z)
           ;CCR = $05 -> 00000101
           ;most assemblers recognize both SR and CCR
           ;so you don't have to specify the length of operand.
华夏公益教科书