新闻  |   论坛  |   博客  |   在线研讨会
65816指令集3
zhchxgh | 2009-07-10 16:44:02    阅读:1542   发布文章

区段移动指令

MVP:正向移动(目标地址>源地址)
MVN:负向移动(目标地址<源地址)

这是65816的新指令。MVN和MVP可以在没有用户干预的情况下移动内存的数据。

这两个指令都是必需的,这样才能确保数据在进行负方向移动时不会覆盖自身。

移动的源地址从X寄存器中取得,目标地址从Y寄存器中取得。移动数据的长度(16位)从累加器中取得,而不需要理会m标志的值。这个长度值应该是实际移动的长度减去1(比如a=$0000,会移动1个字节)。

两个操作数字节指定了来源的64K存储段和目标的64K存储段。操作数字节在汇编程序中的顺序是来源,目标--然而,实际的二进制输出代码会是目标存储段字节,来源存储段字节,最后才是MVN或者MVP的操作码。

当来源地址比目标地址大时,使用MVN进行负方向移动,或者在目标内存段范围小于来源内存段范围时使用MVP。

MVN指令使用X和Y寄存器来指示两个被移动的内存段的底部(开始)地址。通过MVN,数据从X中的来源地址移动到在Y中的目标地址,然后X和Y寄存器递增,累加器递减,直到累加器下溢$FFFF。

当源地址小于目标地址时,使用MVP进行正向移动,或者在目标内存段范围大于来源内存范围时使用MVN。

MVP指令使用X和Y寄存器来指示两个被移动的内存段的顶部地址。数据从X中的来源地址移动到在Y中的目标地址,然后XY寄存器和累加器都递减,直到累加器下溢$FFFF。

如果变址寄存器被设成8位模式(x=1)或处理器被设成6502模拟模式,那么数据移动将会被局限在页面零内,因为高端字节总是零。

可以很容易地在子程序内使用移动指令,然后在运行时动态地修改代码以交换MVN和MVP操作码,这样可以减少代码的长度。

状态寄存器标志不会受移动指令的影响。

寻址方式 语法 操作码 指令长度 周期
区段移动 MVN src,dest 54 3 *
区段移动 MVP src,dest 44 3 *
* 每7个周期移动一个字节

NOP:空操作

和在6502下一样,NOP指令不会影响任何标志

寻址方式 语法 操作码 指令长度 周期
隐式寻址 NOP EA 1 2

ORA:与累加器。

功能和6502下的ORA相同,但是用了新的寻址方式。在16位内存/累加器模式(m=0)下,被操作的数据是16位宽的。低端字节来自有效地址,高端字节来自有效地址的下一个存储单元。

该指令会影响的标志 n-----zc

n:在结果的最高有效位被设置时设置。 z:如果结果是零则设置。 寻址模式 语法 操作码 指令长度 周期 备注
直接寻址 ORA #const
09
2*
2
1
绝对寻址 ORA addr
0D
3
4
1
绝对长程寻址 ORA long
0F
4
5
1
直接页面寻址 ORA dp
05
2
3
1,2
直接页面间接寻址 ORA (dp)
12
2
5
1,2
直接页面间接长程寻址 ORA [dp]
07
2
6
1,2
绝对变址X寻址 ORA addr,X
1D
3
4
1,3
绝对变址X长程寻址 ORA long,X
1F
4
5
1
绝对变址Y寻址 ORA addr,Y
19

3

4
1,3
直接页面变址X寻址 ORA dp,X
15
2
4
1,2
直接页面变址X,间接寻址 ORA (dp,X)
01
2
6
1,2
直接页面间接,变址Y寻址 ORA (dp),Y
11
2
5
1,2,3
直接页面间接长程,变址Y寻址 ORA [dp],Y
17
2
6
1,2
堆栈相对寻址 ORA sr,S
03
2
4
1
堆栈相对间接,变址Y寻址 ORA (sr,S),Y
13
2
7
1
* 如果m=0(16位内存/累加器),则增加一个字节
1 如果m=0(16位内存/累加器),则增加一个周期
2 如果直接页面寄存器的低端字节不为零,则增加一个周期
3 如果增加变址越过页面边界,则增加一个周期

PEA:有效绝对地址压栈

PEA将16位的操作数压入堆栈。堆栈指针减2。该指令不会影响任何标志。不像其他使用汇编程序助记符的指令,PEA是将操作数的值压入堆栈,而不是将位于有效地址的数据压入堆栈。其实它更合适的名字应该是直接数据压栈--不知道为什么它不这么叫。

举例来说:

PEA $1234
会将#$12和#$34依次压栈。 寻址模式 语法 操作码 指令长度 周期
堆栈(绝对)寻址 PEA addr F4 3 5

PEI:有效间接地址压栈

这个65816个指令将有效地址的地址压入堆栈。这个指令总是向堆栈压入16位的数据而不理会m和x状态位的值。

有效地址的下一个存储单位的地址首先被压入堆栈,然后是有效地址的地址被压栈。

举例来说:假如$5678按标准的低端字节/高端字节的格式被储存在$21/$22,然后执行

PEI ($21)
会从$21/$22取出$5678并且压入堆栈。 寻址模式 语法 操作码 指令长度 周期 备注
堆栈(直接页面间接)寻址 PEI (dp) D4 2 6 1
1 如果直接页面寄存器的低端字节不是0,则增加1个周期

PER:有效程序指针相对间接地址压栈

这个指令把程序指针加上16位的操作数,将获得的16位数据压入堆栈。目标地址必须位于当前的64K内存存储段内。用于计算的程序指针的值是PER之后的下一条指令的地址(两个字节)。

相加结果的高端字节首先被压栈,然后是低端字节。

因为该指令用一个相对的偏移量作为操作数,它会对编写重定位代码有帮助。可以将一个未知的运行时地址压入堆栈,然后将该地址出栈以决定程序运行时起点。

该指令的另一种用途是将6502的pha:pha:rts风格的代码的返回地址压入堆栈。

寻址模式 语法 操作码 指令长度 周期
堆栈(程序指针相对长程)寻址 PER lable 62 3 6

A,P,X,Y寄存器压栈,出栈指令:

PHA,PHP,PLA,PLP和他们在6502中的前身基本一样。唯一的不同是在16位累加器/内存(m=0)模式下执行PHA或PLA时,压入堆栈的数据将是16位宽的。(PHP/PLP只在8位上操作)

新的压栈出堆栈指令包括PHY,PLY,PHX和PLX。这四条新指令将变址寄存器压栈或者出栈。当状态寄存器被设置到16位变址寄存器模式(x=0),被压栈和出栈的变址寄存器会按16位上操作。

寻址模式

标志

助记符 操作码 指令长度 周期 备注
堆栈(压栈) - - - - - - - - PHA 48 1 3 1
堆栈(压栈) - - - - - - - - PHP 08 1 3  
堆栈(压栈) - - - - - - - - PHX DA 1 3 2
堆栈(压栈) - - - - - - - - PHY 5A 1 3 2
堆栈(出栈) n - - - - - z - PLA 68 1 4 1
堆栈(出栈) n v m x d i z c PLP 28 1 4  
堆栈(出栈) n - - - - - z - PLX FA 1 4 2
堆栈(出栈) n - - - - - z - PLY 7A 1 4 2
1 如果是16位内存/累加器(m=0),则增加1个周期
2 如果是16位变址寄存器(x=0),则增加1个周期

存储段寄存器压栈,出栈指令:

PHB将数据存储段寄存器的8位数据内容压入堆栈。

PHD将直接页面寄存器的16位数据内容压入堆栈。高端字节被先被压栈,然后是低端字节。

PHK将程序存储寄存器的8位数据内容压入堆栈。

PLB将数据存储段寄存器的单字节内容出栈。这是唯一能直接改变数据存储段寄存器的指令。

PLD将直接页面寄存器的双字节内容出栈。低端字节首先出栈,然后是高端字节。

出栈指令会影响的标志:

n:如果出栈的数据的最高有效位被设置,则设置。 z:如果出栈的数据是零则设置。 寻址模式

标志

助记符 操作码 指令长度 周期
堆栈(压栈) - - - - - - - - PHB 8B 1 3
堆栈(压栈) - - - - - - - - PHD 0B 1 4
堆栈(压栈) - - - - - - - - PHK 4B 1 3
堆栈(出栈) n - - - - - z - PLB AB 1 4
堆栈(出栈) n - - - - - z - PLD 2B 1 5

REP:复位状态位

REP是一个新增的65816指令。当执行时,它会把由单字节直接数据值指定的位复位(清除)。

举例来说明如何清除状态寄存器的位5:

REP #%00100000 ;清除位5
也可以清除多个位: REP #%10110000 ;清除位7,位5和位4
其实任何组合都是可以的。

要设置一个位,可以看SEP指令。

会被影响的标志:nvmxdizc

所有操作数中指定的位都会被清除,其他的位则不受影响。 寻址模式 语法 操作码 指令长度 周期
直接寻址 REP #const C2 2 3

ROL:对内存数据或累加器进行循环左移

ROL和6502下的ROL指令一样地工作。在16位累加器/内存模式(m=0)下,循环移动的数据是16位宽的,先前的位15变成了新的进位标志。低端字节位于有效地址而高端字节位于有效地址的下一个存储单元。

会受影响的标志:n-----zc

n:在结果的最高有效位被设置时设置。 z:如果结果是零则设置。 c:高位(位7或位15)变成新的进位。 寻址模式 语法 操作码 指令长度 周期 备注
累加器寻址

ROL a

2A 1 2  
绝对寻址 ROL addr 2E 3 6 1
直接页面寻址 ROL dp 26 2 5 1,2
绝对变址X寻址 ROL addr,X 3E 3 7 1
直接页面变址X寻址 ROL dp,X 36 2 6 1,2
1 如果m=0(16位内存/累加器),则增加两个周期
2 如果直接页面寄存器的低端字节不为零,则增加一个周期

ROR:内存数据或累加器循环右移

该指令和6502下的ROR一样地工作。在16位内存/累加器模式(m=0)下,被循环移动的数据将是16位宽的(加上进位),低端字节位于有效地址而高端字节位于有效地址的下一个存储单元。

会受影响的标志:n-----zc

n:在结果的最高有效位被设置时设置。 z:如果结果是零则设置。 c:低位变成新的进位。 寻址模式 语法 操作码 指令长度 周期 备注
累加器寻址

ROR a

6A 1 2  
绝对寻址 ROR addr 6E 3 6 1
直接页面寻址 ROR dp 66 2 5 1,2
绝对变址X寻址 ROR addr,X 7E 3 7 1
直接页面变址X寻址 ROR dp,X 76 2 6 1,2
1 如果m=0(16位内存/累加器),则增加两个周期
2 如果直接页面寄存器的低端字节不为零,则增加一个周期

RTI:从中断返回

在6502模拟模式(e=1)下RTI和在旧6502下一样地被处理。在65816的原本模式(e=0)下,RTI还将程序存储寄存器字节从堆栈中弹出。由于有这个特别的字节存在,所以要确保在中断执行时,RTI在和处理器相同的模式(e=?)下执行。

会受影响的标志有:状态寄存器从堆栈弹出,所以所有的标志都受影响。

寻址模式 语法 操作码 指令长度 周期 备注
堆栈寻址(RTI) RTI 40 1 6 1
1 如果在65816原本模式,则增加1个周期

RTL:从子程序长程返回

RTL和RTS差不多,但它还将程序存储寄存器弹出堆栈。这个指令应该和JSR长程指令或者和一个将程序存储段压入堆栈的子程序联合使用。RTL从堆栈弹出24位数据。首先是两个字节的程序指针的低端/高端字节被弹出并且递增,然后是程序存储寄存器被弹出。

RTL不会影响任何标志。

寻址模式 语法 操作码 指令长度 周期
堆栈寻址(RTL) RTL 6B 1 6

RTS:从子程序返回

和6502下的指令一样。不会影响任何标志。

RTS的一种有趣的用法是将返回地址压入堆栈,然后通过RTS运行它。为了使用这种方式来编码,压入堆栈的地址必须至少比真正的子程序地址小1,因为出栈后,处理器会在继续执行之前自动把程序指针加1。当在原本模式中并且使用16位累加器/内存时,这能很容易地用下面的代码完成:

DEC A ;递减16位的累加器。或用DEA。 PHA ;将16位返回地址压栈。 RTS ;返回来执行指令。 寻址模式 语法 操作码 指令长度 周期
堆栈寻址(RTS) RTS 60 1 6

SBC:从累加器减去

SBC也和在6502下一样地工作。唯一的不同,又是增加了一些新的寻址方式,以及数据也许要在16位累加器或者16位内存存储单元中工作的事实。

在16位内存/累加器模式下使用的SBC和ADC会全面地大幅度提高65816 的程序性能,一个程序员能轻易地看出加法和减法子程序在16位方式下操作比在8位方式下操作快多少。

该指令会影响的标志 nv----zc

n:在结果的最高有效位被设置时设置。 v:如果有符号的溢出则设置。 z:如果结果是零则设置。 c:如果不需要无符号借位则设置。 寻址模式 语法 操作码 指令长度 周期 备注
直接寻址 SBC #const
E9
2*
2
1
绝对寻址 SBC addr
ED
3
4
1
绝对长程寻址 SBC long
EF
4
5
1
直接页面寻址 SBC dp
E5
2
3
1,2
直接页面间接寻址 SBC (dp)
F2
2
5
1,2
直接页面间接长程寻址 SBC [dp]
E7
2
6
1,2
绝对变址X寻址 SBC addr,X
FD
3
4
1,3
绝对变址X长程寻址 SBC long,X
FF
4
5
1
绝对变址Y寻址 SBC addr,Y
F9

3

4
1,3
直接页面变址X寻址 SBC dp,X
F5
2
4
1,2
直接页面变址X,间接寻址 SBC (dp,X)
E1
2
6
1,2
直接页面间接,变址Y寻址 SBC (dp),Y
F1
2
5
1,2,3
直接页面间接长程,变址Y寻址 SBC [dp],Y
F7
2
6
1,2
堆栈相对寻址 SBC sr,S
E3
2
4
1
堆栈相对间接,变址Y寻址 SBC (sr,S),Y
F3
2
7
1
* 如果m=0(16位内存/累加器),则增加一个字节
1 如果m=0(16位内存/累加器),则增加一个周期
2 如果直接页面寄存器的低端字节不为零,则增加一个周期
3 如果增加变址越过页面边界,则增加一个周期

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
推荐文章
最近访客