SPMC65系列单片机指令系统
2.1 符号约定:
SPMC65 系列单片机指令按其功能可划分为:
数据传送指令,包括立即数到寄存器、寄存器到寄存器、寄存器到存储器、存储器到寄存器的数据传送操作;
算术运算,包括加、减、比较运算;
逻辑运算,包括与、或、异或、移位等操作;
位操作,包括位测试、位置位、位清除、位取反等操作;
转移指令,包括条件转移、无条件转移、中断返回、子程序调用等操作;
控制指令 ,如开中断、关中断、清除进位、清除负标志等操作;
为了将指令的用法讲解清楚,下表将指令系统叙述过程中要用到的符号列出。
表 2. 1 指令系统叙述过程中要用到的符号
A |
累加器 (A) |
X |
X 寄存器 |
Y |
Y 寄存器 |
PC |
程序指针 (PC) |
SP |
堆栈指针 (SP) |
P |
状态寄存器 (P) |
N |
负标志位( N ):该位指示一个数据或者运算结果的 bit7 的状态。用户可以通过该位进行条件跳转。 |
V |
溢出标志位 (V) :该位仅用于有符号数的算术运算。如果两个同符号数相加或两个不同符号数相减,结果大于 127 或者小于 -128 ,该位置 1 。 |
D |
十进制模式标志位 (D) :在 SPMC65 系列芯片中有两种算术运算模式:二进制模式和十进制模式,该位标明了当前的运算模式。用户可以通过相应的指令来选择一种运算模式。 |
I |
中断屏蔽位 (I) :该位用于使能 / 禁止除“非屏蔽中断源( NMI )”以外的所有中断源。将该位置 1 , CPU 将忽略中断请求,置 0 , CPU 将接受中断请求。 |
Z |
零标志位( Z ):数据和算术运算结果标志位。当数据或算术运算结果为 0 时,该位被置 1 ;为其它值时,该位被置 0 。 |
C |
进位标志( C ):当加法操作中产生进位或减法操作中没有产生借位时,该位被置 1 。此外,移位或循环指令 也会改变该位的值。 |
#dd |
8 位( BIT )的立即数 |
Label |
程序标号 |
; |
程序注释前缀 |
Adr 08 |
8 位存储器地址 |
Adr16 |
16 位存储器地址 |
aa |
8 位存储器地址 |
aaaa |
16 位存储器地址 |
Cycles |
指令周期数, 1 个 Cycle 的时间为 1 个 CPU 时钟周期,即 1/F SYS |
SPMC65 系列单片机的汇编指令格式规定
汇编指令包括四部分,格式如下:
[ 标号 : ] 操作码 [ 操作数 ] [ ; 注释 ]
[ ] 中的内容为可选项 标号:标识了一条指令的位置,可以使用标号作为访问该指令的地址。标号应以字母或下划线‘ _ '开头(局部标号还可以用问号‘?'开头),以冒号‘ : '结束;标号的命名可以取数字、字母和下划线的组合,长度为 2~32 个字符,区分大小写。不要用指令记助符、寄存器名称或系统保留字的字符串作为标号。而宏名可以字母、下划线或百分号 (%) 开头。标号的后缀可以是字母、下划线、问号或井号‘ # '。
操作码: 指令区域,用于写指令。
操作数:操作数可以是程序中的数据或地址。当操作码为单字节时,无操作数。当进行立即数寻址时,操作数为一个字节数据,使用一个符号来标识其所在位置。当操作数作为程序地址时,其实就是一个标号。
注释:注释可以提高程序的可读性。在注释语句的前面应该加一个分号‘ ; '。
例如:
LDA #5 ; 将 8 位立即数 5 载入累加器 A
STA Counter ; 将累加器 A 中的数载入变量 Counter 中
数制
汇编器默认数制为十进制,如果要表示成其它数制,需要给数字加上后缀或前缀。下表列出了各种数制的表达方式。应用时,将其与数值组合即可。
二进制 |
以“ % ”为前缀或以“ B ”、“ b ”为后缀 |
10101011B |
八进制 |
以“ O ”、“ o ”或“ Q ”、“ q ”为后缀 |
253Q |
十进制 |
以“ D ”或“ d” 为后缀或无后缀 |
171 |
十六进制 |
以“ H ”、“ h” 为后缀或以“ $ ”、“ 0X ”、“ 0x ” 为前缀 |
$AB |
字符串定义
字符串必须放在双引号 (“”) 或单引号 (‘ ') 内表示,除非语法上另有所指。
2.2 寻址方式
在计算机中,寻找操作数的方法定义为指令的寻址方式,根据这个原则, SPMC65 系列单片机的寻址方式分为以下 11 种:
立即数寻址( Immediate addressing mode )
绝对寻址( Absolute addressing mode )
零页寻址( Zero page addressing mode )
绝对变址寻址( Absolute indexed addressing mode )
零页变址寻址( Zero page indexed addressing mode )
间接跳转寻址( Indirect addressing mode )
变址间接寻址( Indexed indirect addressing mode )
间接变址寻址( Indirect indexed addressing mode )
隐含寻址( Implied addressing mode )
累加器寻址( Accumulator addressing mode )
相对寻址( Relative addressing mode )
立即数寻址 ( Immediate Addressing Mode )
这种寻址方式的操作数以 8 位立即数的形式出现,紧跟在操作码的后面,立即数用“ # ”号表示,以区别直接地址。
汇编格式: 操作码 #dd
例如: AND #$08
立即数寻址过程如 图 2.1 所示,首先 xx 是由累加器 A 提供,这是由 AND 的操作数决定的, 08 就是立即数,然后进行逻辑与操作。由于 AND 操作数是两个字节,所以执行该操作数后 PC 向后移动两个字。就是 mmmm+2 ,以下同。

图 2. 1 立即数寻址方式示意图
绝对寻址( Absolute addressing mode )
绝对寻址用两个字节 (Adr 16) 来 指明目标操作数地址。
汇编格式: 操作码 Adr16
例子: AND $E030
绝对寻址过程如 图 2.2 所示,操作码(指令) AND 的一个操作数从 $E030 指向的存储单元里直接取得。

图 2. 2 绝对寻址过程示意图
零页寻址( Zero page addressing mode )
零页寻址采用零页(地址范围 $0000~$00FF )的低字节来指明操作数地址(高位地址默认为零)。
汇编格式: 操作码 Adr08
例子: AND $30
零页寻址过程如 图 2.3 所示,操作码(指令) AND 的一个操作数从零页存储单元 $30 中直接取得。

图 2. 3 零页寻址过程示意图
绝对变址寻址( Absolute indexed addressing mode )
绝对变址寻址使用一个双字节基址和一个变址指针(寄存器 X 或 Y ) 来 指明目标操作数地址。
汇编格式: 操作码 Adr 16, X
或: 操作码 Adr 16, Y
例子: LDA $E500,X
绝对变址寻址的过程如 图 2.4 所示,由绝对地址(基址)与变址指针( X 寄存器)的地址相加得到的地址里的数作为操作数。

图 2. 4 绝对变址寻址过程示意图
零页变址寻址( Zero page indexed addressing mode )
零页变址寻址使用零页地址作为基址,基址与变址指针(寄存器 X 或 Y )相加 来 指明目标操作数地址。
汇编格式: 操作码 Adr 08, X
或: 操作码 Adr 08, Y
例子: LDA $75,X
零页变址寻址的过程如 图 2.5 所示,由零页地址(基址)与变址指针( X 寄存器)的地址相加得到的地址里的数作为操作数。

图 2. 5 零页变址寻址过程示意图
间接跳转寻址( Indirect addressing mode )
间接跳转寻址只能用于 JMP 指令中,它用 16 位地址作为程序跳转地址的指针。
汇编格式: 操作码 ( Adr 16)
例子: JMP ( $F600)
如下图所示,间接跳转寻址将 $F600 与 $F601 两单元中的数据组成的 16 位地址 $ppqq 作为 PC 的跳转地址( $pp 、 $qq 为存储器中的数值)。

图 2. 6 间接跳转寻址过程示意图
变址间接寻址( Indexed indirect addressing mode )
变址间接寻址采用“ 8 位地址+变址指针 X ”来 指明目标操作数地址。 在此寻址模式下,只能采用 X 寄存器作为变址指针。
汇编格式: 操作码 (Adr 08, X)
例子: AND ($30, X)
变址间接寻址如 图 2.7 所示,首先 $30 与变址指针( X 寄存器)中的值 $63 相加,其结果 $93 作为目标操作数地址的指针,它所指向的数值 $qq 与下一个存储单元中的数值 $pp 共同组成了 16 位的目标操作数地址。地址 $ppqq 指向的内容 $yy 就是目标操作数。

图 2. 7 变址间接寻址过程示意图
间接变址寻址( Indirect indexed addressing mode )
间接变址寻址采用“ 8 位地址”来 指明目标操作数的基址,再加上 变址指针( Y 寄存器)作为目标操作数的地址 。 在此寻址模式下,只能采用 Y 寄存器作为变址指针。
汇编格式: 操作码 (aa), Y
例子: LDA ($20), Y
间接变址寻址如 图 2.8 所示,由地址 $20 里的数据 $32 作为基址地址的低 8 位,下一个地址 $21 里的数据 $01 作为基址地址的高 8 位,二者组成的 16 位基址 $0132 加上指针( Y 寄存器)中的数据 $15 形成目标操作数地址 $0147 ,目标操作数地址里的数据作为操作数。

图 2.8 间接变址寻址
隐含寻址( Implied addressing mode )
隐含寻址是特殊指令对应的特殊寻址方式,它的源操作数和目标操作数的地址都由指令默认。
汇编格式: 操作码
例子: TAX ; 将累加器内容传送到 X 寄存器中
CLC ; 清除进位标志
累加器寻址( Accumulator addressing mode )
累加器寻址采用累加器 A 作为指令操作数。
汇编格式: 操作码 A
例子: ROL A ; 累加器 A 内容循环左移
ASL A ; 累加器 A 的内容算数左移
相对寻址( Relative addressing mode )
相对寻址使用一个 8 位地址来定义目标操作数的 地址,该寻址方式仅用在条件跳转指令中,最大的向前跨度为 127 字节,最大向后跨度为 128 字节。
汇编格式: 操作码 Adr 08
例子: BCC M127
BCC P128
相对地址寻址过程如 图 2.9 所示,其中 M127 与 P128 都是标号

图 2. 9 相对寻址过程示意图
2.3 指令系统
指令概述
指令依照其用途可分为六类:数据传送类指令、算术运算类指令、逻辑运算类指令、位操作指令、转移类指令、控制类指令。它们的具体分类及用途详见 表 2.2 。
表 2. 2 SPMC65 指令分类列表
类别 |
用途 |
指令 |
数据传送指令 |
立即数到寄存器、寄存器到寄存器、寄存器到存储器、存储器到寄存器的数据传送操作 |
LDA 、 LDX 、 LDY 、 STA 、 STX 、 STY 、 TAX 、 TXA 、 TAY 、 TYA 、 TXS 、 TSX 、 PHA 、 PHP 、 PLA 、 PLP |
算术运算指令 |
加、减、比较运算 |
ADC 、 SBC 、 DEC 、 DEX 、 DEY 、 INC 、 INX 、 INY 、 CMP 、 CPX 、 CPY |
逻辑运算指令 |
与、或、异或、移位等操作 |
AND 、 ORA 、 EOR 、 ASL 、 LSR 、 ROL 、 ROR 、 BIT |
控制转移指令 |
条件转移、无条件转移、中断返回、子程序调用等操作 |
BCS 、 BCC 、 BEQ 、 BNE 、 BMI 、 BPL 、 BVS 、 BVC 、 JMP 、 JSR 、 RTS 、 RTI |
位操作指令 |
位置位、位清除、位取反、位测试等操作 |
SET 、 CLR 、 INV 、 TST |
处理器控制指令 |
开中断、关中断、清除进位、清除负标志等操作 |
CLC 、 CLD 、 CLI 、 CLV 、 SEC 、 SED 、 SEI 、 NOP |
数据传送指令
数据传送是把源操作数传送到目标地址的过程,是计算机最基本、最重要的一种操作。在实际应用中,数据传送指令使用的比例是最高的。
1. LDA
LDA 的作用是将数据送入累加器 A 中,具体格式参见下表:
表 2.3 指令 LDA
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
LDA #dd |
A9H |
2 |
2 |
LDA aa |
A5H |
2 |
3 |
LDA aa, X |
B5H |
2 |
4 |
LDA aaaa |
ADH |
3 |
4 |
LDA aaaa, X |
BDH |
3 |
4 * |
LDA aaaa, Y |
B9H |
3 |
4 * |
LDA (aa, X) |
A1H |
2 |
6 |
LDA (aa), Y |
B1H |
2 |
6 * |
* 如果数据寻址时超出了一页的范围,需要再加一个指令周期,一页的大小为 256 个字节。
该指令对 P 标志位的影响见下表:
表 2 . 4 LDA 指令对 P 标志位的影响
N:将bit7的值赋给N
Z:结果为0时置1
[ 例 ] :
LDA #$F0 ; 把立即数 $F0 传送至累加器 A
LDA $F0 ; 把位于 $F0 地址的数据复制到累加器 A
2. LDX
LDX 的作用是将数据送入 X 寄存器中。具体格式参见下表:
表 2 . 5 指令 LDX
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
LDX #dd |
A2H |
2 |
2 |
LDX aa |
A6H |
2 |
3 |
LDX aa, Y |
B6H |
2 |
4 |
LDX aaaa |
AEH |
3 |
4 |
LDX aaaa, Y |
BEH |
3 |
4 * |
* 如果数据寻址时超出了一页的范围 , 需要再加一个指令周期
该指令对 P 标志位的影响见下表:
表 2 . 6 LDX 指令对 P 标志位的影响
N:将bit7的值赋给N
Z:结果为0置1
[ 例 ] :
LDX #$F0 ; 把 立即数 $F0 传送至 X 寄存器
LDX $F0 ; 把位于 $F0 地址的数据复制到 X 寄存器
3. LDY
LDY 的作用是将数据送入 Y 寄存器中。具体格式参见下表:
表 2 . 7 指令 LDY
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
LDY #dd |
A0H |
2 |
2 |
LDY aa |
A4H |
2 |
3 |
LDY aa, X |
B4H |
2 |
4 |
LDY aaaa |
ACH |
3 |
4 |
LDY aaaa, X |
BCH |
3 |
4 * |
* 如果数据寻址时超出了一页的范围,需要再加一个指令周期
该指令对 P 标志位的影响见下表:
表 2 . 8 LDY 指令对 P 标志位的影响
N:将bit7的值赋给N
Z:结果为0置1
[ 例 ] :
LDY #$F0 ; 把 立即数 $F0 传送至 Y 寄存器
LDY $F0 ; 把位于 $F0 地址的数据复制到 Y 寄存器
LDX #$12 ; 把立即数 $12 传送至 X 寄存器
LDY $E005,X ; 把地址为 $E017($E005+$12) 的数据复制到 Y 寄存器
4. STA
STA 的作用是将累加器 A 的值送入存储器。具体格式参见下表:
表 2 . 9 指令 STA
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
STA aa |
85H |
2 |
3 |
STA aa, X |
95H |
2 |
4 |
STA aaaa |
8DH |
3 |
4 |
STA aaaa, X |
9DH |
3 |
4 |
STA aaaa, Y |
99H |
3 |
4 |
STA (aa, X) |
81H |
2 |
6 |
STA (aa), Y |
91H |
2 |
6 |
该指令对标志寄存器 P 不产生影响。
[ 例 ] :
LDA #$12 ; 把立即数 $12 送至累加器
STA $78 ; 把累加器中的数据 $12 复制到地址为 $78 的存储单元
STX
STX 的作用是将寄存器 X 的值送入存储器中。具体格式参见下表:
表 2 . 10 指令 STX
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
STX aa |
86H |
2 |
3 |
STX aa, Y |
96H |
2 |
4 |
STX aaaa |
8EH |
3 |
4 |
该指令对标志寄存器 P 不产生影响。
[ 例 ] :
LDX #$12 ; 把立即数 12 送至寄存器 X
STX $78 ; 把寄存器 X 中的数据 $12 复制到地址为 $78 的存储单元
6. STY
STY 的作用是将寄存器 Y 的值送入存储器中。具体格式参见下表:
表 2 . 11 指令 STY
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
STY aa |
84H |
2 |
3 |
STY aa, X |
94H |
2 |
4 |
STY aaaa |
8CH |
3 |
4 |
该指令对标志寄存器 P 不产生影响。
[ 例 ] :
LDY #$12 ; 把立即数 $12 送至寄存器 Y
STY $78 ; 把寄存器 Y 中的数据 $12 复制到地址为 $78 的存储单元
LDX #$10 ; 把立即数 $10 送至寄存器 X
STY $63,X ; 把寄存器 Y 中的数据 $12 复制到地址为 $73 ( $63+$10 )的存储单元
7. TAX
TAX 的作用是将累加器 A 的值送入寄存器 X 中。具体格式参见下表:
表 2 . 12 指令 TAX
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
TAX |
AAH |
1 |
2 |
该指令对 P 标志位的影响见下表:
表 2 . 13 TAX 指令对 P 标志位的影响
N:将bit7的值赋给N
Z:运算结果为零置1
[ 例 ] :
LDA #$17 ; 把立即数 $17 送至累加器 A
TAX ; 把累加器 A 中的数值 $17 复制到寄存器 X 中
8. TXA
TXA的作用是将 X 寄存器的值送入累加器 A 中 。参见下表:
表 2 . 14 指令 TXA
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
TXA |
8AH |
1 |
2 |
该指令对 P 标志位的影响见下表:
表 2 . 15 TXA 指令对 P 标志位的影响
N:将bit7的值赋给N
Z:运算结果为零置1
[ 例 ] :
LDX #$17 ; 把立即数 $17 送至寄存器 X
TXA ; 把寄存器 X 中的数值 $17 复制到累加器 A 中
9. TAY
TAY 的作用是将累加器 A 的值送入寄存器 Y 中。具体格式参见下表:
表 2 . 16 指令 TAY
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
TAY |
A8H |
1 |
2 |
该指令对 P 标志位的影响见下表:
表 2 . 17 TAY 指令对 P 标志位的影响
N:将bit7的值赋给N
Z:运算结果为零置1
[ 例 ] :
LDA #$17 ; 把立即数 $17 送至累加器 A
TAY ; 把累加器 A 中的数值 $17 复制到寄存器 X 中
10. TYA
TYA 的作用是将 Y 寄存器的值传送到累加器 A 中。具体格式参见下表:
表 2 . 18 指令 TYA
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
TYA |
98H |
1 |
2 |
该指令对 P 标志位的影响见下表:
表 2 . 19 TYA 指令对 P 标志位的影响
N:将bit7的值赋给N
Z:运算结果为零置1
[ 例 ] :
LDY #$17 ; 把立即数 $17 送至寄存器 Y
TYA ; 把寄存器 Y 中的数值 $17 复制到累加器 A 中
11. TXS
TXS的作用是 将 X 寄存器的值传送到堆栈指针 SP 的低 8 位中 。具体格式参见下表:
表 2 . 20 指令 TXS
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
TXS |
9AH |
1 |
2 |
TXS 指令对标志寄存器 P 不产生影响。
[ 例 ] :
LDX #$FC ; 把立即数 $FC 送至寄存器 X
TXS ; 把 X 中的值赋给堆栈指针 SP 的低 8 位, SP 的值将变为 $FC
12. TSX
TSX 的作用是将堆栈指针 SP 中的值送入 X 寄存器中。具体格式参见下表:
表 2 . 21 TSX 指令对 P 标志位的影响
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
TSX |
BAH |
1 |
2 |
该指令对 P 标志位的影响见下表:
表 2 . 22 TAY 指令对 P 标志位的影响
N:将bit7的值赋给N
Z:运算结果为零置1
13. PHA
PHA的作用是 将累加器 A 的值压入堆栈 。该指令产生的操作是:首先将累加器 A的值传送到堆栈指针SP所指向的存储单元,然后使SP的值减小1。具体格式参见下表:
表 2 . 23 指令 PHA
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
PHA |
48H |
1 |
3 |
该指令对标志寄存器 P 不产生影响。
[ 例 ] :
LDX #$FF ; X ? $FF 立即数 0xFF( 即 $FF) 载入寄存器 X
TXS ; SP ? $FF, 立即数 0xFF( 即 $FF) 载入堆栈寄存器 SP, 堆栈指针指向 $01FF
LDA #$35 ; A ? $35
PHA ; [$1FF] ? $35, SP ? SP - 1, 此时 $35 被传送到 $01FF 单元, SP 的值变为 $1FE
14. PHP
PHP的作用是 将状态标志寄存器的值压入堆栈, 主要作用是保护现场。该指令产生的操作是:首先将标志寄存器 P的值传送到堆栈指针SP所指向的存储单元,然后使SP的值减小1。具体格式参见下表:
表 2 . 24 指令 PHP
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
PHP |
08H |
1 |
3 |
该指令对标志寄存器 P 不产生影响。
15. PLA
PLA的作用是 将堆栈内容弹出给 A 。该指令产生的操作是:首先使堆栈指针 SP 的值增加 1 ,然后把 SP 指向的存储单元中的数值传送给累加器 A 。 具体格式参见下表:
表 2 . 25 指令 PLA
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
PLA |
68H |
1 |
4 |
该指令对 P 标志位的影响见下表:
表 2 . 26 PLA 指令对 P 标志位的影响
N:将bit7的值赋给N
Z:运算结果为零置1
[ 例 ] :
LDX #$FF ; X ? $FF 立即数 0xFF( 即 $FF) 载入寄存器 X
TXS ; SP ? $FF 立即数 0xFF( 即 $FF) 载入堆栈寄存器 SP, 堆栈指针指向 $01FF
LDA #$35 ; A ? $35
PHA ; [SP] ? $35, SP ? SP – 1, 此时 $35 被传送到 $01FF 单元, SP 的值变为 $FE
LDA #$78 ; A ? $78
PLA ; SP ? SP + 1, A ? [SP], 此时 SP 变为 $FF , $01FF 单元中的数值 $35 被传
; 送至累加器 A
16. PLP
PLP的作用是 将堆栈中的内容弹出给状态标志寄存器 P 。该指令首先将堆栈指针 SP 的值增加 1 ,然后将 SP 指向的存储单元中的数值赋给标志寄存器 P 。 具体格式参见下表:
表 2 . 27 指令 PLP
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
PLP |
28H |
1 |
4 |
该指令对 P 标志位的影响见下表:
表 2 . 28 PLP 指令对 P 标志位的影响
PLP指令影响所有P标志。
算术运算指令
SPMC65 的算术运算指令主要包括带进位加法、减法,寄存器或存储器的自增、自减,以及比较运算指令。
1. ADC
ADC 是累加器 A 的带进位加法指令,该指令将累加器 A 中的数值与指定的操作数相加,再加上进位标志 C 的值,得到的结果赋给累加器 A 。具体格式参见下表:
表 2 . 29 指令 ADC
汇编指令格式 |
操作码 |
字节数 |
指令周期(Cycles) |
ADC #dd |
69H |
2 |
2 |
ADC aa |
65H |
2 |
3 |
ADC aa, X |
75H |
2 |
4 |
ADC aaaa |
6DH |
3 |
4 |
ADC aaaa, X |
7DH |
3 |
4* |
ADC aaaa, Y |
79H |
3 |
4* |
ADC (aa, X) |
61H |
2 |
6 |
ADC (aa), Y |
71H |
2 |
6* |
* 如果数据寻址时超出了一页的范围,需要再加一个指令周期
该指令对 P 标志位的影响见下表:
表 2 . 30 指令 ADC 对 P 标志位的影响
N:将bit7的值赋给N
V:仅用于有符号数算术运算,两个同符号数相加或异符号数相减,结果大于127或小于-128时,该位置1
Z:结果为0时置1
C:最高位产生进位时,该位被置1
D:*为1表示当前处于十进制模式
[ 例 1] :
LDA #$45 ; A ? $45
CLC ; 将进位标志 C 设置为 0 ,参见 2.3.7 节关于 CLC 指令的介绍
ADC #$32 ; A ? A + $32 + C ,此时累加器 A 的值变为 $77 , N=0, V=0, Z=0, C=0
[ 例 2] :
LDA #$25 ; A ? $25
SEC ; 将进位标志 C 设置为 1 ,参见 2.3.7 节关于 SEC 指令的介绍
ADC #$18 ; A ? A + $18 + C ,此时累加器 A 的值变为 $3E , N=0, V=0, Z=0, 由于未发
; 生进位, C 的值变为 0
[ 例 3] :
LDA #$45 ; A ? $45
STA $68 ; [$68] ? A ,该句将 $45 传送到地址为 $68 的存储单元
CLC ; 将进位标志 C 设置为 0 ,参见 2.3.7 节关于 CLC 指令的介绍
LDA #$72 ; A ? $72
ADC $68 ; A ? A + [$68] + C ,即 ($72 + $45 + 0) ,此时累加器 A 的值变为 $B7 , Z=0 ,
; C=0 ,由于相当于两个同符号数相加,结果大于 127 ,所以 V=1 ,由于结果
; 最高位为 1 ,所以 N=1
[ 例 4] :
SED ; 将十进制模式标志 D 设置为 1 ,切换到十进制运算模式,参见 2.3.7 节关于 SED
; 指令的介绍
LDA #$25 ; A ? $25
SEC ; 将进位标志 C 设置为 1 ,参见 2.3.7 节关于 SEC 指令的介绍
ADC #$18 ; 十进制运算, A ? (BCD)A + (BCD)$18 + C ,累加器 A 的值变为 $44 , C=0,
; N=0, Z=0, V=0 ,可与例 2 对比
2. SBC
SBC 是累加器 A 的带借位减法指令,该指令将累加器 A 中的数值与指定的操作数相减,若进位标志 C 的值是 0 则再减去 1 ,得到的结果赋给累加器 A ,即 A ? A - data - 。具体格式参见下表:
表 2 . 31 指令 SBC
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
SBC #dd |
E9H |
2 |
2 |
SBC aa |
E5H |
2 |
3 |
SBC aa, X |
F5H |
2 |
4 |
SBC aaaa |
EDH |
3 |
4 |
SBC aaaa, X |
FDH |
3 |
4 * |
SBC aaaa, Y |
F9H |
3 |
4 * |
SBC (aa, X) |
E1H |
2 |
6 |
SBC (aa), Y |
F1H |
2 |
6 * |
* 如果数据寻址时超出了一页的范围,需要再加一个指令周期
该指令对 P 标志位的影响见下表:
表 2 . 32 指令 SBC 对 P 标志位的影响
N:将bit7的值赋给N
V:仅用于有符号数算术运算,两个同符号数相加或异符号数相减,结果大于127或小于-128时,该位置1
Z:结果为0时置1
C: 计算过程未发生借位则C置1,发生借位则C置0
D: *为1表示当前处于十进制模式
[ 例 1] :
LDA #$45 ; A ? $45
CLC ; 将进位标志 C 设置为 0 ,参见 2.3.7 节关于 CLC 指令的介绍
SBC #$32 ; A ? A - $32 - ,此时累加器 A 的值变为 $12 , N=0, V=0, Z=0, 由于未发生
; 借位,所以 C=1
[ 例 2] :
LDA #$39 ; A ? $39
SEC ; 将进位标志 C 设置为 1 ,参见 2.3.7 节关于 SEC 指令的介绍
SBC #$47 ; A ? A - $47 - ,此时累加器 A 的值变为 $F2 (借位,相当于 $139-$47 ), V=0,
; Z=0, 由于发生了借位,所以 C=0 ,由于结果的 bit7 为 1 ,所以 N=1
[ 例 3] :
LDA #$62 ; A ? $62
STA $68 ; [$68] ? A ,该句将 $62 传送到地址为 $68 的存储单元
SEC ; 将进位标志 C 设置为 1 ,参见 2.3.7 节关于 SEC 指令的介绍
LDA #$94 ; A ? $94
SBC $68 ; A ? A – [$68] - ,即 ($94 - $62 - 0) ,此时累加器 A 的值变为 $32 , Z=0, N=0,
; 由于未发生借位,所以 C=1 ,由于相当于两个不同符号数相减( $94 作为有符
; 号数使用时相当于 -108 10 , $68 相当于 98 10 )结果小于 -128 10 ,所以 V=1
[ 例 4] :
SED ; 将十进制模式标志 D 设置为 1 ,切换到十进制运算模式,参见 2.3.7 节关于 SED
; 指令的介绍
LDA #$39 ; A ? $39
SEC ; 将进位标志 C 设置为 1 ,参见 2.3.7 节关于 SEC 指令的介绍
SBC #$47 ; 十进制运算, A ? (BCD)A - (BCD)$47 - ,累加器 A 的值变为 $92 (发生
; 借位,相当于 139 – 47 - 0 ), C=0, Z=0, V=0, N=1 (结果的最高位为 1 ),可
; 以与例 2 对比。
3. DEC
DEC 的作用是对存储器中的数值进行减 1操作 , 具体格式参见下表:
表 2 . 33 指令 DEC
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
DEC aa |
C6H |
2 |
5 |
DEC aa, X |
D6H |
2 |
6 |
DEC aaaa |
CEH |
3 |
6 |
DEC aaaa, X |
DEH |
3 |
6 |
该指令对 P 标志位的影响见下表:
表 2 . 34 指令 DEC 对 P 标志位的影响
N:将bit7的值赋给N
Z:结果为0置1
[ 例 1] :
LDA #$45 ; A ? $45
STA $68 ; [$68] ? A ,此时 $68 存储单元内的数值是 $45
DEC $68 ; [$68] ? [$68] – 1 ,此时 $68 存储单元内的数值变为 $44
[ 例 2] :
SED ; 将十进制模式标志 D 设置为 1 ,切换到十进制运算模式,参见 2.3.7 节关于 SED
; 指令的介绍
LDA #$30 ; A ? $30
LDX #$12 ; X ? $12
STA $63,X ; [$63 + X] ? A ,此时 $30 被传送到 $75 存储单元中
DEC $63,X ; [$63 + X] ? [$63 + X] – 1 ,此时 $75 存储单元内的数值变为 $2F ,证明十进
; 制运算模式对 DEC 指令无效。
4. DEX
DEX 的作用是使 X 寄存器内的数值减 1 , 具体格式参见下表:
表 2 . 35 指令 DEX
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
DEX |
CAH |
1 |
2 |
该指令对 P 标志位的影响见下表:
表 2 . 36 指令 DEX 对 P 标志位的影响
N:将bit7的值赋给N
Z:结果为0置1
[ 例 ] :
LDX #$36 ; X ? $36
DEX ; X ? X – 1 ,此时寄存器 X 内的数值变为 $35
5. DEY
DEY 的作用是使 Y 寄存器内的数值减 1 , 具体格式参见下表:
表 2 . 37 指令 DEY
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
DEY |
88H |
1 |
2 |
该指令对 P 标志位的影响见下表:
表 2 . 38 指令 DEY 对 P 标志位的影响
N:将bit7的值赋给N
Z:结果为0置1
[ 例 ] :
LDY #$00 ; Y ? $00 , N=0, Z=1
DEY ; Y ? Y – 1 ,此时寄存器 Y 内的数值变为 $FF , N=1,Z=0
6. INC
INC 的作用是对存储器中的数值进行加 1操作 , 具体格式参见下表:
表 2 . 39 指令 INC
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
INC aa |
E6H |
2 |
5 |
INC aa, X |
F6H |
2 |
6 |
INC aaaa |
EEH |
3 |
6 |
INC aaaa, X |
FEH |
3 |
6 |
该指令对 P 标志位的影响见下表:
表 2 . 40 指令 INC 对 P 标志位的影响
N:将bit7的值赋给N
Z:结果为0置1
[ 例 1] :
LDA #$45 ; A ? $45
STA $68 ; [$68] ? A ,此时 $68 存储单元内的数值是 $45
INC $68 ; [$68] ? [$68] + 1 ,此时 $68 存储单元内的数值变为 $46
[ 例 2] :
LDA #$FF ; A ? $FF
LDX #$12 ; X ? $12
STA $63,X ; [$63 + X] ? A ,此时 $FF 被传送到 $75 存储单元中
INC $63,X ; [$63 + X] ? [$63 + X] + 1 ,此时 $75 存储单元内的数值变为 $00
7. INX
INX 的作用是使 X 寄存器内的数值加 1 ,具体格式参见下表:
表 2 . 41 指令 INX
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
INX |
E8H |
1 |
2 |
该指令对 P 标志位的影响见下表:
表 2 . 42 指令 INX 对 P 标志位的影响
N:将bit7的值赋给N
Z:结果为0置1
[ 例 ] :
LDX #$36 ; X ? $36
INX ; X ? X + 1 ,此时寄存器 X 内的数值变为 $37
8. INY
INY 的作用是使 Y 寄存器内的数值加 1 ,具体格式参见下表:
表 2 . 43 指令 INY
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
INY |
C8H |
1 |
2 |
该指令对 P 标志位的影响见下表:
N:将bit7的值赋给N
Z:结果为0置1
[ 例 ] :
LDY #$36 ; Y ? $36
INY ; Y ? Y + 1 ,此时寄存器 Y 内的数值变为 $37
9. CMP
CMP 的作用是 将累加器 A 的值与指定操作数进行比较,方法是:累加器 A 的值与指定的操作数相减,若结果为负,则 C 标志置 0 ,否则 C 置 1 ;若结果为 0 ,则 Z 标志置 1 。 CMP 指令只改变标志寄存器,而不会改变累加器 A 的值。该指令通常与条件转移类指令配合使用(参见 2.3.5 节)。 具体格式如下:
表 2 . 44 指令 CMP
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
CMP #dd |
C9H |
2 |
2 |
CMP aa |
C5H |
2 |
3 |
CMP aa, X |
D5H |
2 |
4 |
CMP aaaa |
CDH |
3 |
4 |
CMP aaaa, X |
DDH |
3 |
4 * |
CMP aaaa, Y |
D9H |
3 |
4 * |
CMP (aa, X) |
C1H |
2 |
6 |
CMP (aa), Y |
D1H |
2 |
6 * |
该指令对 P 标志位的影响见下表:
表 2 . 42 指令 INX 对 P 标志位的影响
N:将bit7的值赋给N
Z:结果为0置1
[ 例 ] :
LDX #$36 ; X ? $36
INX ; X ? X + 1 ,此时寄存器 X 内的数值变为 $37
8. INY
INY 的作用是使 Y 寄存器内的数值加 1 ,具体格式参见下表:
表 2 . 43 指令 INY
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
INY |
C8H |
1 |
2 |
该指令对 P 标志位的影响见下表:
N:将bit7的值赋给N
Z:结果为0置1
[ 例 ] :
LDY #$36 ; Y ? $36
INY ; Y ? Y + 1 ,此时寄存器 Y 内的数值变为 $37
9. CMP
CMP 的作用是 将累加器 A 的值与指定操作数进行比较,方法是:累加器 A 的值与指定的操作数相减,若结果为负,则 C 标志置 0 ,否则 C 置 1 ;若结果为 0 ,则 Z 标志置 1 。 CMP 指令只改变标志寄存器,而不会改变累加器 A 的值。该指令通常与条件转移类指令配合使用(参见 2.3.5 节)。 具体格式如下:
表 2 . 44 指令 CMP
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
CMP #dd |
C9H |
2 |
2 |
CMP aa |
C5H |
2 |
3 |
CMP aa, X |
D5H |
2 |
4 |
CMP aaaa |
CDH |
3 |
4 |
CMP aaaa, X |
DDH |
3 |
4 * |
CMP aaaa, Y |
D9H |
3 |
4 * |
CMP (aa, X) |
C1H |
2 |
6 |
CMP (aa), Y |
D1H |
2 |
6 * |
表 2 . 51 指令 AND 对 P 标志位的影响
N:将bit7的值赋给N
Z:结果为0时置1
[ 例 ] :
LDA #%10110100 ; A ? %10110100
AND #%11010010 ; A ? A and %11010010 ,执行此句后累加器的值为 10010000
2. ORA
对累加器 A 中的操作数与指定的操作数进行逻辑“或”运算。即两操作数对应位中的任一个为 1 (或两个都为 1 ),则该位的结果为 1 ,否则为 0 。“或”运算的结果送回累加器 A 。 具体格式参见下表:
表 2 . 52 指令 ORA
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
ORA #dd |
09H |
2 |
2 |
ORA aa |
05H |
2 |
3 |
ORA aa, X |
15H |
2 |
4 |
ORA aaaa |
0DH |
3 |
4 |
ORA aaaa, X |
1DH |
3 |
4 * |
ORA aaaa, Y |
19H |
3 |
4 * |
ORA (aa, X) |
01H |
2 |
6 |
ORA (aa), Y |
11H |
2 |
6 * |
* 如果数据寻址时超出了一页的范围,需要再加一个指令周期
该指令对 P 标志位的影响见下表:
表 2 . 53 指令 ORA 对 P 标志位的影响
N:将bit7的值赋给N
Z:结果为0置1
[ 例 ] :
LDA #%10110100 ; A ? %10110100
STA $68 ; [$68] ? A ,此句将 %10110100 存入地址为 $68 的单元
LDA #%11010010 ; A ? %11010010
ORA $68 ; A ? A or [$68] ,即 %11010010 和 %10110100 进行“或”运算,执行此句后
;A 的值将变为 %11110110
3. EOR
这条指令对累加器 A 的值与指定的操作数进行“异或”运算。当两数的对应位不相同时(即一个为 1 ,
另一个为 0 ),该位的异或结果为 1 ;否则该位的异或结果为 0 。异或运算的结果送回到累加器 A 中。 具体格式参见下表:
表 2 . 54 指令 EOR
汇编指令格式 |
操作码 |
字节数 |
指令周期( Cycles) |
EOR #dd |
49H |
2 |
2 |
EOR aa |
45H |
2 |
3 |
EOR aa, X |
55H |
2 |
4 |
EOR aaaa |
| |