跳到主要内容

寄存器运算

本分册收录寄存器类指令 0x10~0x21、寄存器-立即数运算指令 0x2A~0x2E,以及专用的 0x30 数码管编码与 0x32 三寄存器运算:写入立即数、复制、增减、端口送取数、移位、位逻辑、寄存器间与寄存器-立即数四则运算、随机数、拼字与字节交换。

所有寄存器 R00~RFF 均为 16 位。当寄存器号放在 16 位整体操作数中传送时,按 00 + 寄存器号的形式书写——例如 001C 表示寄存器 R1C。操作数解释方式与端口体系表统一定义在简述中。

0x10 写寄存器(FZ)​

向指定寄存器写入一个立即数:R[P01] = P10P11。

000  10  001C  03E8
001 0F 0000 0000
002 10 0003 00FF R03 = 255(P10P11=00FF 为16位整体立即数)

第 000 行把数值 03E8(十进制 1000)写入 R1C。运行结果可以在 OLED 屏的寄存器页面实时查看。

信息
操作数数值/范围备注
P0000忽略
P0100~FF目标寄存器号
P10P110000~FFFF16 位整体:立即数

0x11 寄存器赋值(RFZ)​

把一个寄存器的值复制到另一个寄存器:R[A] = R[B]。

000  11  001D  001C
001 0F 0000 0000
002 11 0004 0003 R04 = R03(把源 R03 复制到目标 R04)

第 000 行把 R1C 的值复制到 R1D;R1C 自身保持不变。

信息
操作数数值/范围备注
P0000忽略
P0100~FF目标寄存器 A
P1000忽略
P1100~FF源寄存器 B

0x12 增减寄存器(ZJ)​

把寄存器的值增加或减少一个 16 位增量,每条指令还可以单独约定是否允许溢出。

000  10  001C  FF00    R1C = FF00
001 12 001C 03E8 R1C 增加 03E8,不允许溢出
002 0F 0000 0000
003 12 0003 000A 模式00:R03 += 10,加法禁溢出(最大到 FFFF 为止)
004 12 0103 000A 模式01:R03 += 10,加法许溢出(超过 FFFF 回绕)
005 12 1003 000A 模式10:R03 -= 10,减法禁溢出(最小到 0 为止)
006 12 1103 000A 模式11:R03 -= 10,减法许溢出(小于 0 回绕)

FF00 + 03E8 = 1 02E8,超出了 16 位范围。不允许溢出时,数值被封顶在 FFFF;允许溢出时,寄存器直接回绕为 02E8。

信息
操作数数值/范围备注
P0000增加,不允许溢出(上限 FFFF)
01增加,允许溢出(回绕)
10减少,不允许溢出(下限 0000)
11减少,允许溢出(回绕)
P0100~FF寄存器号
P10P110000~FFFF16 位整体:增减量

0x13 送数(SS)​

把一个寄存器的整值写到端口上(端口体系见简述):

  • Port1 取低 8 位(8 路数字 IO,即 LED 网络)。写 Port1 前会先恢复输出方向并立即刷新硬件,解除 QS 造成的输入方向切换。
  • Port2 取低 4 位(4 路 IO/PWM 引脚)。
  • Port4~6 按位驱动 PCA9685 模块 0/1/2 的 16 个通道。
  • Port0 / Port3 为只读端口,写入被忽略。
000  10  0004  00FF    R04 = 00FF
001 13 0004 0001 Port1 = R04,8 个 LED 全亮
002 0F 0000 0000
003 13 0005 0001 R05 整体值送到 Port1(8路LED逐位点亮,如 R05=0F 则 LED0~3 亮)
004 13 0006 0002 R06 整体值送到 Port2(4路,只用低4位)
005 13 0007 0004 R07 整体值送到 PCA9685 模块0(16通道逐位输出)
信息
操作数数值/范围备注
P0000忽略
P0100~7F源寄存器号
P1000忽略
P1101Port1 — 8 路数字 IO(LED 网络)
02Port2 — 4 路 IO/PWM 引脚
04~06Port4~6 — PCA9685 模块 0/1/2,各 16 通道
00 / 03只读端口,写入被忽略

0x14 取数(QS)​

读取整个端口并存入寄存器,端口的每个引脚对应数值的一位(引脚 0 → bit 0):

  • Port0 — 7 个板载按钮(bit0~bit6,bit7 = 0)。
  • Port1 — 8 路数字 IO。读 Port1 前会先把 8 个引脚全部切换为输入方向(上拉),LED 网络呈高阻态、可由外部器件驱动;之后再执行 0x13 SS 即可恢复输出方向。
  • Port2 — 4 路 IO/PWM 引脚(bit0~bit3)。
  • Port3 — 16 路 ADS1115 通道:通道 n 的毫伏读数高于 2500 时 bit n = 1。
  • Port4~6 为只写端口,不可读取。
000  14  0001  0000    R01 = Port0(7 个按钮)
001 0F 0000 0000
002 14 0005 0000 读 Port0(7个按钮的按下状态位图)→ R05
003 14 0006 0001 读 Port1 → R06;读前 8 脚自动转输入方向(上拉)
004 14 0007 0003 读 Port3(16路AD,每路毫伏值>2500 记1)→ R07
信息
操作数数值/范围备注
P0000忽略
P0100~7F目标寄存器号
P1000忽略
P1100Port0 — 7 个板载按钮
01Port1 — 8 路数字 IO(先切换为输入方向)
02Port2 — 4 路 IO/PWM 引脚
03Port3 — ADS1115 通道,高于 2500 mV 记 1

0x15 移位(XHYW)​

把寄存器的位向左或向右移动 1~15 位,可选择是否循环。

000  10   0007  8009    R07 = 8009
001 15 0007 0002 R07 右移 2 位
002 0F 0000 0000
003 15 0003 0004 模式00 右移:R03 右移4位(设 R03=8001 → 0800)
004 15 0103 0004 模式01 循环右移:移出的低位绕回高位
005 15 1003 0004 模式10 左移:R03 左移4位
006 15 1103 0004 模式11 循环左移:移出的高位绕回低位

设 R07 = 8009 = 1000 0000 0000 1001。普通右移 2 位会把最低的 2 位移出,得到 0010 0000 0000 0010 = 2002;循环右移时移出的 2 位从左侧移入,得到 0110 0000 0000 0010 = 6002。

信息
操作数数值/范围备注
P0000右移
01循环右移
10左移
11循环左移
P0100~FF寄存器号
P1000忽略
P1100~0F移位位数(超过 0F 不执行)

0x16 位取反(QF)​

把寄存器的每一位按位取反。

000  10  0007  8009    R07 = 8009
001 16 0007 0000 R07 按位取反
002 0F 0000 0000
003 16 0003 0000 R03 按位取反(设 R03=00FF → FF00)

8009 = 1000 0000 0000 1001,按位取反后 → 0111 1111 1111 0110 = 7FF6,存回 R07。

信息
操作数数值/范围备注
P0000忽略
P0100~FF寄存器号
P10P110000忽略

0x17 位与(WY)​

对两个寄存器做按位与运算,结果存入前一个寄存器:R[dst] &= R[src]。

000  10  0007  8009    R07 = 8009
001 10 0009 FF00 R09 = FF00
002 17 0007 0009 R07 = R07 按位与 R09
003 0F 0000 0000
004 17 0003 0004 R03 &= R04(按位与,结果存回 R03)

1000 0000 0000 1001 与 1111 1111 0000 0000 按位与 = 1000 0000 0000 0000 — R07 变为 8000,R09 保持不变。

信息
操作数数值/范围备注
P0000忽略
P0100~FF目标寄存器(存结果)
P1000忽略
P1100~FF源寄存器

0x18 位或(WH)​

对两个寄存器做按位或运算,结果存入前一个寄存器:R[dst] |= R[src]。操作数格式与 0x17 相同。

000  10  0007  8009    R07 = 8009
001 10 0009 FF00 R09 = FF00
002 18 0007 0009 R07 = R07 按位或 R09
003 0F 0000 0000
004 18 0003 0004 R03 |= R04(按位或,结果存回 R03)

1000 0000 0000 1001 或 1111 1111 0000 0000 按位或 = 1111 1111 0000 1001 — R07 变为 FF09。

信息
操作数数值/范围备注
P0000忽略
P0100~FF目标寄存器(存结果)
P1000忽略
P1100~FF源寄存器

0x19 位异或(WYH)​

对两个寄存器做按位异或运算,结果存入前一个寄存器:R[dst] ^= R[src]。操作数格式与 0x17 相同。

000  10   0007  8009    R07 = 8009
001 10 0009 FF00 R09 = FF00
002 19 0007 0009 R07 = R07 按位异或 R09
003 0F 0000 0000
004 19 0003 0004 R03 ^= R04(按位异或,结果存回 R03)

1000 0000 0000 1001 异或 1111 1111 0000 0000 = 0111 1111 0000 1001 — R07 变为 7F09。

信息
操作数数值/范围备注
P0000忽略
P0100~FF目标寄存器(存结果)
P1000忽略
P1100~FF源寄存器

0x1A 寄存器加法(RJIA)​

两个寄存器相加,结果存入前一个寄存器:R[dst] += R[src]。

000  10    0008  1234    R08 = 1234
001 10 0006 0020 R06 = 0020
002 1A 0008 0006 R08 = R08 + R06
003 0F 0000 0000
004 1A 0003 0004 R03 += R04

1234 + 0020 = 1254 — R08 变为 1254。结果只保留真实和的低 16 位(超出 16 位的进位丢失)。

信息
操作数数值/范围备注
P0000忽略
P0100~FF目标寄存器(存结果)
P1000忽略
P1100~FF源寄存器

0x1B 寄存器减法(RJIAN)​

两个寄存器相减,结果存入前一个寄存器:R[dst] −= R[src]。操作数格式与 0x1A 相同。

000  10     0008  1234    R08 = 1234
001 10 0006 0020 R06 = 0020
002 1B 0008 0006 R08 = R08 - R06
003 0F 0000 0000
004 1B 0003 0004 R03 -= R04

1234 − 0020 = 1214 — R08 变为 1214。

信息
操作数数值/范围备注
P0000忽略
P0100~FF目标寄存器(存结果)
P1000忽略
P1100~FF源寄存器

0x1C 寄存器乘法(RCHENG)​

两个寄存器相乘,结果存入前一个寄存器:R[dst] ×= R[src]。操作数格式与 0x1A 相同。

000  10     0008  1234    R08 = 1234
001 10 0006 0020 R06 = 0020
002 1C 0008 0006 R08 = R08 × R06
003 0F 0000 0000
004 1C 0003 0004 R03 ×= R04

1234 × 0020 = 2 4680 — 真实乘积需要 17 位以上,只保留低 16 位,R08 变为 4680。

信息
操作数数值/范围备注
P0000忽略
P0100~FF目标寄存器(存结果)
P1000忽略
P1100~FF源寄存器

0x1D 寄存器除法(RCHU)​

两个寄存器相除,整数商存入前一个寄存器:R[dst] ÷= R[src]。操作数格式与 0x1A 相同。

警告

这是整数之间的除法——只保留商,余数舍去(余数请用 0x1E RQY 计算)。若源寄存器为 0000,将触发除零异常。

000  10    0008  1234    R08 = 1234
001 10 0006 0020 R06 = 0020
002 1D 0008 0006 R08 = R08 ÷ R06(取商)
003 0F 0000 0000
004 1D 0003 0004 R03 ÷= R04(整数商;R04=0 触发异常)

1234 ÷ 0020 = 0091(4660 ÷ 32 = 145,余数舍去)— R08 变为 0091。

信息
操作数数值/范围备注
P0000忽略
P0100~FF目标寄存器(存结果)
P1000忽略
P1100~FF源寄存器(除数,不得为 0000)

0x1E 寄存器取余(RQY)​

两个寄存器相除,只保留余数并存入前一个寄存器:R[dst] %= R[src]。操作数格式与 0x1A 相同。

警告

若源寄存器为 0000,将触发除零异常。

000  10    0008  1234    R08 = 1234
001 10 0006 0020 R06 = 0020
002 1E 0008 0006 R08 = R08 % R06
003 0F 0000 0000
004 1E 0003 0004 R03 %= R04(余数存回 R03)

1234 % 0020 = 0014(4660 mod 32 = 20)— R08 变为 0014。

信息
操作数数值/范围备注
P0000忽略
P0100~FF目标寄存器(存结果)
P1000忽略
P1100~FF源寄存器(除数,不得为 0000)

0x1F 随机数(SJS)​

生成一个随机数并存入目标寄存器:R[reg] = rand()(低 16 位)。

000  1F  0005  0000    R05 = 随机数
001 0F 0000 0000
信息
操作数数值/范围备注
P00P010000~007F16 位整体:目标寄存器号(写法 00 + 寄存器号)
P10P110000忽略

0x20 高低成字(GDCZ)​

取两个寄存器的低字节拼成一个 16 位字并存入目标寄存器:目标寄存器的低字节作为结果的高 8 位,源寄存器的低字节作为结果的低 8 位。

000  10    0005  2450    R05 = 2450
001 10 0006 FF00 R06 = FF00
002 20 0005 0006 R05 = low(R05) : low(R06)
003 0F 0000 0000
004 20 0005 0003 R05 = R05 低8位拼 R03 低8位(R05低字节在高位、R03低字节在低位)

R05 的低字节(50)成为结果的高字节,R06 的低字节(00)成为结果的低字节 — R05 变为 5000。

备注

0x20/0x21 的双 16 位整体操作数格式来自固件代码分析,建议上机复核。

信息
操作数数值/范围备注
P00P010000~007F16 位整体:目标寄存器号(写法 00 + 寄存器号)
P10P110000~007F16 位整体:源寄存器号(写法 00 + 寄存器号)

0x21 高低交换(GDJH)​

把目标寄存器的高 8 位与低 8 位互换。

000  10    0005  1234    R05 = 1234
001 21 0005 0000 R05 = 3412
002 0F 0000 0000
003 21 0005 0005 R05 高低字节交换(设 R05=1234 → 3412)
备注

0x20/0x21 的双 16 位整体操作数格式来自固件代码分析,建议上机复核。

信息
操作数数值/范围备注
P00P010000~007F16 位整体:目标寄存器号(写法 00 + 寄存器号)
P10P110000忽略

0x2A 加立即数(JIA)​

把立即数加到寄存器上:R[reg] += P10P11。

000  10  0007  8009    R07 = 8009
001 2A 0007 03E8 R07 += 03E8
002 0F 0000 0000
003 2A 0003 000A R03 += 10(16位立即数加法)

8009 + 03E8 = 83F1 — R07 变为 83F1。

信息
操作数数值/范围备注
P0000忽略
P0100~FF寄存器号
P10P110000~FFFF16 位整体:立即数

0x2B 减立即数(JIAN)​

从寄存器中减去立即数:R[reg] −= P10P11。操作数格式与 0x2A 相同。

000  10   0007  83F1    R07 = 83F1
001 2B 0007 03E8 R07 -= 03E8
002 0F 0000 0000
003 2B 0003 000A R03 -= 10

83F1 − 03E8 = 8009 — R07 变为 8009。

信息
操作数数值/范围备注
P0000忽略
P0100~FF寄存器号
P10P110000~FFFF16 位整体:立即数

0x2C 乘立即数(CHENG)​

把寄存器乘以立即数:R[reg] ×= P10P11。操作数格式与 0x2A 相同。

000  10    0007  03E8    R07 = 03E8(十进制 1000)
001 2C 0007 0003 R07 ×= 0003
002 0F 0000 0000
003 2C 0003 000A R03 ×= 10

1000 × 3 = 3000 = 0BB8 — R07 变为 0BB8。

信息
操作数数值/范围备注
P0000忽略
P0100~FF寄存器号
P10P110000~FFFF16 位整体:立即数

0x2D 除立即数(CHU)​

把寄存器除以立即数,保留整数商:R[reg] ÷= P10P11。操作数格式与 0x2A 相同。

警告

若立即数除数为 0000,将触发除零异常。

000  10   0007  0BB8    R07 = 0BB8(十进制 3000)
001 2D 0007 0003 R07 ÷= 0003
002 0F 0000 0000
003 2D 0003 000A R03 ÷= 10(整数商;立即数 0 触发异常)

3000 ÷ 3 = 1000 = 03E8 — R07 变为 03E8。

信息
操作数数值/范围备注
P0000忽略
P0100~FF寄存器号
P10P110000~FFFF16 位整体:立即数(除数,不得为 0000)

0x2E 取余立即数(QY)​

计算寄存器除以立即数的余数:R[reg] %= P10P11。操作数格式与 0x2A 相同。

警告

若立即数除数为 0000,将触发除零异常。

000  10  0007  03E9    R07 = 03E9(十进制 1001)
001 2E 0007 0003 R07 %= 0003
002 0F 0000 0000
003 2E 0003 000A R03 %= 10(结果 0~9,常用于拆个位)

1001 mod 3 = 2 = 0002 — R07 变为 0002。

信息
操作数数值/范围备注
P0000忽略
P0100~FF寄存器号
P10P110000~FFFF16 位整体:立即数(除数,不得为 0000)

0x30 编码七段(BMQD)​

把数值转换成两段七段数码管段码,供 0x44 SSE 驱动板载数码管时直接使用。

源寄存器的值被拆成两位数字,各自查段码表后打包进目标寄存器:

  • 高 8 位 = 十位(高位数字)的段码。
  • 低 8 位 = 个位(低位数字)的段码。
  • 段码位序:bit7 = a … bit0 = dp。

拆位方式由 P11 选择:十进制(00)把 0~99 的数值拆成十位与个位;十六进制(01)把源寄存器的低字节拆成高半字节与低半字节(00~FF)。

P10 = 01 时整个 16 位结果整体取反——共阳数码管的段线低电平点亮,需用此方式;P10 = 00 时光直出(共阴惯例)。

000  10    0001  003C    R01 = 60
001 30 0102 0100 R02 = 60 的段码,整体取反(共阳)
002 0F 0000 0000
003 30 0304 0000 同上但直出不取反(配共阴数码管)
004 30 0506 0101 按十六进制拆位(P11=01):R05=3C → 段码(3)(C),配共阳取反

第 001 行把 R01 = 60 拆成 6 和 0,查得段码(6 为 0xBE,0 为 0xFC)后按共阳硬件取反 — R02 = 4103:高字节为十位段码,低字节为个位段码。基于本指令的完整扫描示例见 0x44 SSE。

信息
操作数数值/范围备注
P0000~FF源寄存器号(取其低 8 位拆位)
P0100~FF目标寄存器号
P1000直出(共阴惯例)
01整个 16 位结果取反(共阳数码管)
P1100十进制拆位:数值 0~99 → 十位 + 个位
01十六进制拆位:低字节 → 高半字节 + 低半字节

0x32 三寄存器运算(TJYS)​

对两个源寄存器执行一次运算:R[dst] = R[s0] op R[s1],运算种类由运算码选择。

信息
操作数数值/范围备注
P0000~FF目标寄存器(存结果)
P0100~0D运算码,见下表
P1000~FF源寄存器 0(左操作数)
P1100~FF源寄存器 1(右操作数)

运算码表:

运算码运算运算码运算
00按位与08写(R[s0] = R[s1])
01按位或09移位
02按位异或0A拷贝
03加法0B低字节拼字
04减法0CR[s0] 字节交换
05乘法0D取余
06除法
07按位取反(反转 R[s0])
警告

运算码 07、08、0A、0B、0C 的结果写入**源寄存器 0(P10)**而不是目标寄存器——这些运算码下 P00 操作数不起作用。除法(06)与取余(0D)请确保源寄存器 1 不为零。

000  10    0001  0005    R01 = 5
001 10 0002 0003 R02 = 3
002 32 0303 0102 R03 = R01 + R02
003 0F 0000 0000
004 32 0503 0607 运算码03(加):R05 = R06 + R07
005 32 0500 0607 运算码00(与):R05 = R06 & R07
006 32 0508 0600 运算码08(写):R05 = R06

第 002 行使用运算码 03(加法)对源寄存器 R01、R02 做运算,结果存入目标寄存器 — R03 = 5 + 3 = 8。