惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

F
Full Disclosure
Recorded Future
Recorded Future
T
Tenable Blog
S
Securelist
C
CERT Recently Published Vulnerability Notes
T
Threatpost
S
Schneier on Security
A
Arctic Wolf
The Hacker News
The Hacker News
C
CXSECURITY Database RSS Feed - CXSecurity.com
Know Your Adversary
Know Your Adversary
P
Privacy International News Feed
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
The Register - Security
The Register - Security
Cisco Talos Blog
Cisco Talos Blog
AWS News Blog
AWS News Blog
K
Kaspersky official blog
T
True Tiger Recordings
T
Threat Research - Cisco Blogs
V
Vulnerabilities – Threatpost
P
Palo Alto Networks Blog
T
The Exploit Database - CXSecurity.com
小众软件
小众软件
B
Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Microsoft Azure Blog
Microsoft Azure Blog
Cyberwarzone
Cyberwarzone
C
Cybersecurity and Infrastructure Security Agency CISA
T
Tor Project blog
Spread Privacy
Spread Privacy
Malwarebytes
Malwarebytes
P
Proofpoint News Feed
F
Fox-IT International blog
F
Fortinet All Blogs
P
Privacy & Cybersecurity Law Blog
G
GRAHAM CLULEY
量子位
Latest news
Latest news
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
博客园 - 叶小钗
Project Zero
Project Zero
T
Tailwind CSS Blog
N
Netflix TechBlog - Medium
Martin Fowler
Martin Fowler
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
IntelliJ IDEA : IntelliJ IDEA – the Leading IDE for Professional Development in Java and Kotlin | The JetBrains Blog
I
Intezer
博客园_首页
腾讯CDC
H
Hackread – Cybersecurity News, Data Breaches, AI and More
D
Darknet – Hacking Tools, Hacker News & Cyber Security

敖苛记

如何安装 Claude Code 并用 cc-switch 配置国内大模型 | 敖苛记 如何在 Windows 安装 Git | 敖苛记 如何安装 Windows 的包管理器 scoop 并配置国内镜像 | 敖苛记 给 Deepseek 发 <think> 之后,它就串台了? | 敖苛记 如何处理 PowerShell 中文乱码问题 | 敖苛记 Java 面向对象笔记:接口、抽象类、多态与重写 | 敖苛记 如何使用 ollama 和 open-webui 搭建自己的本地 AI 助手 | 敖苛记 如何使用 archinstall 安装 Arch Linux | 敖苛记 如何使用 Ventoy 制作一个便捷的 Arch Linux to go | 敖苛记
TEC-2008教学计算机完整知识汇总 | 敖苛记
敖苛 · 2026-04-20 · via 敖苛记

一、基础概念

1.1 标志位(C/Z/V/S)

标志位用于记录运算结果的状态,供条件转移指令判断使用。

标志位定义

标志位全称含义说明
CCarry 进位- 加法:最高位产生进位,C=1;无进位,C=0
- 减法:最高位产生借位,C=0;无借位,C=1
ZZero 零- 运算结果为 0,Z=1
- 运算结果不为 0,Z=0
VoVerflow 溢出- 有符号数运算结果溢出,V=1
- 有符号数运算结果不溢出,V=0
SSign 符号- 运算结果为正数(最高位为0),S=0
- 运算结果为负数(最高位为1),S=1

标志位示例:二进制加法

text
0101  (二进制数1)
+ 0011  (二进制数2)
-------
 1000  (二进制和)
  • 进位标志位(C):无进位产生,C=0
  • 溢出标志位(V):0101(+5)与 0011(+3)均为正数,结果 1000 符号位为 1(负数),发生有符号数溢出,V=1(4 位有符号数范围为 −8~+7,5+3=8 超出上界)
  • 零标志位(Z):结果不为 0,Z=0
  • 符号标志位(S):结果 1000 符号位为 1,S=1(结果被解释为负数)

进位 (C) 和溢出 (V) 的区别

进位是无符号数运算的溢出,溢出是有符号数运算的溢出,二者相互独立:

  1. 示例 1:无进位无溢出
    text
    0011  (3)
    + 0011  (3)
    -------
      0110  (6) 正确
    
    • 无进位,C=0;无溢出,V=0
  2. 示例 2:有进位无溢出
    text
    1111  (-1)
    + 0111  (7)
    -------
     1 0110 (6) 正确
     ---
     进位
    
    • 有进位,C=1;不产生溢出,V=0
  3. 示例 3:有进位有溢出
    text
    1100  (-4)
    + 1000  (-8)
    -------
     1 0100 (截断后为+4,实际结果为-12) 溢出
     --
     进位
    
    • 有进位,C=1;产生溢出:V=1(负数 + 负数 = 正数,违反有符号数运算规则)

1.2 指令格式与寻址方式

TEC-2008 是 16 位教学计算机,支持单字和双字指令。

指令格式结构

说明

  • 单字指令:16 位,最高 8 位为操作码;最低 8 位分两种用法:
    1. 运算指令:拆分为 4 位目的寄存器 + 4 位源寄存器
    2. IO/转移指令:作为完整 8 位端口地址或转移偏移量
  • 双字指令:32 位,第二个字用于存放 16 位立即数、直接地址或变址偏移量。

支持的寻址方式

  • 寄存器寻址
  • 寄存器间接寻址([寄存器],以寄存器值为内存地址)
  • 立即数寻址
  • 直接地址寻址
  • 变址寻址
  • 相对寻址
  • 堆栈寻址
  • IO 端口地址

二、完整指令系统

2.1 指令分类

TEC-2008 共支持 29 条基本指令,分为 6 大类:

  1. 数据移动指令 4 条MVRRMVRDLDRRSTRR
  2. 堆栈操作指令 4 条PUSHPOPPSHFPOPF
  3. 输入输出指令 2 条INOUT
  4. 算术逻辑运算指令 11 条ADDSUBANDXORTESTCMPORDECINCSHLSHR
  5. 转移指令 6 条JMPAJRJRCJRNCJRZJRNZ
  6. 子程序调用与返回指令 2 条CALARET

2.2 指令命名规则

缩写全称说明
MVMOVE
LDLOAD
STSTORE
SHSHIFT
JMPJUMP
CALCALL
RETRETURN
JRJUMP RELATIVE
RREGISTER
DDATA
AADDRESS
FFLAGS

2.3 A 组指令

A 组指令为单字运算与相对转移指令,8 位操作码范围000xxxxx0100xxxx:CZVS 列中,* 表示影响该标志位,. 表示不影响标志位,顺序为 C、Z、V、S。

指令格式汇编语句操作数个数CZVS功能说明
00000000 DR SRADD DR, SR2****DR ← DR + SR
00000001 DR SRSUB DR, SR2****DR ← DR - SR
00000010 DR SRAND DR, SR2.*..DR ← DR and SR
00000011 DR SRCMP DR, SR2****DR - SR(不存结果,仅更新标志位)
00000100 DR SRXOR DR, SR2.*..DR ← DR xor SR
00000101 DR SRTEST DR, SR2****DR and SR(不存结果,仅更新标志位)
00000110 DR SROR DR, SR2.*..DR ← DR or SR
00000111 DR SRMVRR DR, SR2....DR ← SR
00001000 DR0000DEC DR1****DR ← DR - 1
00001001 DR0000INC DR1****DR ← DR + 1
00001010 DR0000SHL DR1*...DR, C ← DR * 2(逻辑左移,最高位移入C)
00001011 DR0000SHR DR1*...DR, C ← DR / 2(逻辑右移,最低位移入C)
01000001 OFFSETJR ADR1....无条件相对跳转到 ADR
01000100 OFFSETJRC ADR1....C=1时相对跳转到 ADR
01000101 OFFSETJRNC ADR1....C=0时相对跳转到 ADR
01000110 OFFSETJRZ ADR1....Z=1时相对跳转到 ADR
01000111 OFFSETJRNZ ADR1....Z=0时相对跳转到 ADR

2.4 B/D 组指令

B/D 组指令为内存操作、IO、堆栈、子程序等指令,8 位操作码范围1000xxxx(B组)或 1100xxxx(D组)。 :CZVS 列中,* 表示影响该标志位,. 表示不影响标志位,顺序为 C、Z、V、S。

指令格式汇编语句操作数个数CZVS功能说明
10000000 00000000 ADR(16 位)JMPA ADR1....无条件绝对跳转到 ADR
10000001 DR SRLDRR DR, [SR]2....DR ← [SR](寄存器间接寻址,从内存加载)
10000010 I/O PORTIN I/O PORT1....R0 ← [I/O PORT](从端口读入,固定存入R0)
10000011 DR SRSTRR [DR], SR2....[DR] ← SR(寄存器间接寻址,写入内存)
10000100 00000000PSHF0....标志寄存器FLAG入栈
10000101 0000 SRPUSH SR1....寄存器SR的值入栈
10000110 I/O PORTOUT I/O PORT1....[I/O PORT] ← R0(向端口输出,固定取自R0)
10000111 DR0000POP DR1....DR ← 栈顶出栈数据
10001000 DR0000 DATA(16 位)MVRD DR, DATA2....DR ← DATA(加载16位立即数)
10001100 00000000POPF0****FLAG ← 栈顶出栈数据(恢复全部标志位)
10001111 00000000RET0....子程序返回
11001110 00000000 ADR(16 位)CALA ADR1....调用首地址为 ADR 的子程序

2.5 扩展指令

扩展指令操作码不在基本指令范围内,需通过交叉汇编器的扩展指令表加载后才能使用。

指令格式汇编语句CZVS功能说明
00100000 DR SRADC DR, SR****DR ← DR + SR + C(带进位加)
00100001 DR SRSBB DR, SR****DR ← DR - SR - C(带借位减)
00101010 DR0000RCL DR*...带进位循环左移,最高位移入C,C移入最低位
00101011 DR0000RCR DR*...带进位循环右移,最低位移入C,C移入最高位
00101100 DR0000ASR DR*...算术右移,保持符号位不变
00101101 DR0000NOT DR....DR ← ~DR(按位取反)
01100000 00000000JMPR....无条件寄存器间接跳转(目标地址在 R11:R10)
01100100 OFFSETJRS ADR....S=1 时相对跳转
01100101 OFFSETJRNS ADR....S=0 时相对跳转
01101100 00000000CLC*...清进位标志,C=0
01101101 00000000STC*...置进位标志,C=1
01101110 00000000EI....开中断
01101111 00000000DI....关中断
11100000 00000000CALR....寄存器间接调用子程序(目标地址在 R11:R10)
11100100 DR SRLDRA DR, [ADDR]....直接地址加载,DR ← [ADDR]
11100100 DR SRLDRX DR, [SR+ADDR]....变址寻址加载,DR ← [SR + ADDR]
11100110 DR SRSTRX [SR+ADDR], DR....变址寻址存储,[SR + ADDR] ← DR
11100111 DR SRSTRA [ADDR], DR....直接地址存储,[ADDR] ← DR
11101111 00000000IRET****中断返回(恢复 PC 和标志位)

三、汇编程序设计示例

3.1 例 1:输出单个字符 '6'

功能:在屏幕上输出显示一个字符 '6'。

asm
A 2000	          ; 地址从16进制的2000开始(内存RAM区的起始地址)
2000: MVRD R0, 36	; 把字符'6'的ASCII码送入R0
2002: OUT	80	    ; 输出显示字符'6',80为串口数据端口地址
2003: RET		      ; 每个用户程序都必须用RET指令结束
2004: 		        ; 按回车键即结束源程序的输入过程

3.2 例 2:计算 1 到 10 的累加和

功能:计算 1 到 10 的累加和,运行后用 R 命令查看 R1 中的结果。

asm
A 2060
2060: MVRD R1, 0000	; 置累加和的初值为0
2062: MVRD R2, 000A	; 最大的加数(10)
2064: SUB	R3, R3		; 预置参加累加的数为0
2065: INC	R3		    ; 得到下一个参加累加的数
2066: ADD	R1, R3		; 累加计算
2067: CMP	R3, R2		; 判断是否累加完
2068: JRNZ 2065		  ; 未完,开始下一轮累加
2069: RET

3.3 例 3:循环输出 ASCII 可打印字符

功能:在显示器屏幕上循环显示 95 个(包括空格字符)可打印字符。

程序代码

asm
A 2000	          ; 从内存的2000单元开始建立用户的第一个程序
2000: MVRD R1, 7E ; 向寄存器传送直接数,7E是'~'的ASCII码
2002: MVRD R0, 20	; 20是空格的ASCII码,从空格开始输出
2004: OUT	80		  ; 通过串行接口输出R0低位字节内容到显示器屏幕
2005: PUSH R0		  ; 保存R0寄存器的内容到堆栈中
2006: IN 81		    ; 读串口状态端口,bit0=1表示输出完成
2007: SHR	R0		  ; R0寄存器的内容右移一位,bit0移入进位标志C
2008: JRNC 2006		; C≠1则输出未完成,继续查询
2009: POP	R0		  ; 从堆栈中恢复R0寄存器的原内容
200A: CMP	R0, R1	; 比较两个寄存器的内容,相等则Z=1
200B: JRZ	200E		; Z=1则跳转到程序结束
200C: INC	R0		  ; R0自增,取下一个字符
200D: JR 2004		  ; 无条件跳转继续输出
200E: RET		      ; 子程序返回指令,教学计算机的用户程序必须用RET结束

运行结果

text
>G 2000
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmno
pqrstuvwxyz{|}~
R0=007E  R1=007E  R2=20F5  R3=0000  SP=2780  PC=2200  R6=0000  R7=0000  R8=0000
R9=0000  R10=0000  R11=0000  R12=0000  R13=0000  R14=2612  R15=0000  F=11000000

ASCII 码字符集

L\H000001010011100101110111
0000NULDLESP0@P`p
0001SOHDC1!1AQaq
0010STXDC2"2BRbr
0011ETXDC3#3CScs
0100EOTDC4$4DTdt
0101ENQNAK%5EUeu
0110ACKSYN&6FVfv
0111BELETB'7GWgw
1000BSCAN(8HXhx
1001HTEM)9IYiy
1010LFSUB*:JZjz
1011VTESC+;K[k{
1100FFFS,<L|l|
1101CRGS-=M]m}
1110SORS.>N^n~
1111SIUS/?O_oDEL

3.4 例 4:数字字符输入过滤

功能:从键盘上键入多个属于 '0' 到 '9' 的数字符并在屏幕上显示,遇非数字符结束程序。

asm
A 2040
2040: IN 81		      ; 读串口状态端口,bit1=1表示有键盘输入
2041: SHR	R0		    ; 第一次右移,bit0移入C
2042: SHR	R0		    ; 第二次右移,bit1移入C
2043: JRNC 2040		  ; 无输入则循环检测(C=0时跳转)
2044: IN 80		      ; 把输入字符读到R0低位字节
2045: MVRD R1, 00FF
2047: AND	R0, R1		; 将R0的高位字节清0
2048: MVRD R2, 0030	; '0'的ASCII码
204A: MVRD R3, 0039	; '9'的ASCII码
204C: CMP	R0, R2		; 判输入字符是否小于'0'
204D: JRNC 2053		  ; 小于'0',跳转到程序结束处
204E: CMP	R3, R0		; 判输入字符是否大于'9'
204F: JRNC 2053		  ; 大于'9',跳转到程序结束处
2050: OUT	80		    ; 输出刚输入的数字符
2051: JMPA 2044		  ; 转去等待下一个字符输入
2053: RET

说明

  • CMP 实际执行减法(不存结果)。无符号比较时,R0 < R2 发生借位,C=0;否则 C=1

3.5 例 5:内存读写与大小写转换

功能:读出指定内存中的大写字母字符,将其显示到屏幕上,转换为小写字母后再写回存储器的原存储单元。 操作步骤:用 E 命令送入 6 个字符 'A'~'F' 到内存 20F0 开始的存储区域中,运行后用 D 命令查看。

主程序

asm
A 2080
2080: MVRD R3, 0006	; 指定被读数据的个数
2082: MVRD R2, 20F0	; 指定被读、写数据内存区首地址
2084: LDRR R0, [R2]	; 寄存器间接寻址,读内存字符到R0
2085: CALA 2100		  ; 调用子程序,入口地址为2100
2087: DEC	R3		    ; 剩余字符数减1
2088: JRZ	208B		  ; 个数为0则结束程序
2089: INC	R2		    ; 内存地址自增
208A: JR 2084		    ; 循环处理下一个字符
208B: RET

子程序

asm
A 2100
2100: OUT	80		    ; 输出R0中的字符
2101: MVRD R1, 0020	; 大写转小写的偏移量
2103: ADD	R0, R1		; 转换为小写字母
2104: STRR [R2], R0	; 写回原内存单元
2105: IN 81		      ; 查询串口输出状态
2106: SHR	R0
2107: JRNC 2105		  ; 输出未完成则等待
2108: RET			      ; 子程序返回

3.6 例 6:子程序调用:大小写转换

功能:主程序完成从键盘读入字符并显示,调用子程序将大写字母转为小写并再次显示。

主程序

asm
A 2040
2040: IN 81		    ; 检测键盘输入
2041: SHR	R0
2042: SHR	R0
2043: JRNC 2040
2044: IN 80		    ; 读取输入字符到R0
2045: OUT	80		  ; 显示原字符
2046: PUSH R0	    ; 保存R0
2047: IN 81		    ; 等待输出完成
2048: SHR	R0
2049: JRNC 2047
204A: POP	R0		  ; 恢复R0
204B: CALA 2050	  ; 调用转换子程序
204D: JMPA 2040	  ; 循环读取
204F: RET

子程序

asm
A 2050
2050: MVRD R1, 0020 ; 大写转小写偏移量
2052: ADD	R0, R1		; 转换字符编码
2053: OUT	80		    ; 显示小写字符
2054: RET			      ; 子程序返回

运行结果

text
>G 2040
AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz

说明:程序无输入判断逻辑,会持续运行。


3.7 例 7:批量内存读写测试

功能:将 A~F 写入内存 2240 开始的区域,并显示出来。

程序录入(错误版本)

asm
>A 2220
2220: MVRD R3, 6
2222: MVRD R2, 223f
2224: MVRD R1, 40
2226: INC	R2
2227: INC	R1
2228: STRR R2, R1		; 错误:寄存器间接寻址必须加[]
      ^Error
2228: STRR [R2], R1	; 正确写法
2229: LDRR R0, [R2]
222A: OUT	80
222B: IN 81
222C: SHR	R0
222D: JRNC 202b		  ; 错误:相对跳转地址超出范围
      ^Error
222D: JRNC 222b		  ; 正确写法
222E: DEC	R3
222F: JRNC 2226		  ; 错误:应使用JRNZ判断循环
2230: RET

运行前内存

text
>D 2240
2240 0000 0000 0000 0000 0000 0000 0000 0000

运行结果

text
>G 2220
ABCDEF

运行后内存

text
>D 2240
2240 0041 0042 0043 0044 0045 0046 0000 0000

3.8 输入输出轮询机制

1. 输出完成等待循环

串口状态定义:81端口bit0=1表示输出完成。

asm
2028: IN 81		  ; 读取串口输出状态
2029: SHR	R0		; bit0移入进位标志C
202A: JRNC 2028	; C=0表示未完成,循环等待

测试建议:去掉这三行后,字符可能输出不完整或乱码。

2. 键盘输入检测循环

串口状态定义:81端口bit1=1表示有键盘输入。

asm
2044: IN 81		  ; 读取键盘输入状态
2045: SHR	R0		; 第一次右移
2046: SHR	R0		; 第二次右移,bit1移入C
2047: JRNC 2044	; C=0表示无输入,循环检测

测试建议:去掉这4行后,程序会直接读取旧数据,无法正常响应按键。

3. PUSH/POP 保护寄存器的作用

OUT 80 输出后需轮询 IN 81,该指令会覆盖R0中的字符数据,因此用堆栈保存恢复:

asm
2005: PUSH R0	  ; 保存待显示的字符
2006: IN 81		  ; 读取状态,覆盖R0
2007: SHR	R0
2008: JRNC 2006
2009: POP	R0		; 恢复原字符

四、程序调试与问题排查

4.1 常见错误与修正

错误示例:跳转指令写错

批量内存读写程序中,将JRNZ写成JRNC,导致循环只执行一次。

错误版本反汇编

asm
>U 2220
2220: MVRD R3, 0006
2222: MVRD R2, 223F
2224: MVRD R1, 0040
2226: INC	R2
2227: INC	R1
2228: STRR [R2], R1
2229: LDRR R0, [R2]
222A: OUT	0080
222B: IN 0081
222C: SHR	R0
222D: JRNC 222B
222E: DEC	R3
222F: JRNC 2226 ; 错误:应该用JRNZ
2230: RET

错误原因

DEC R3 后 R3≠0,Z=0;无借位C=1,JRNC判断C=0不成立,不跳转。

修正方法

text
>A 222F
222F: JRNZ 2226

4.2 其他常见错误

  1. STRR 指令遗漏括号:寄存器间接寻址必须加[],错误STRR R2, R1→正确STRR [R2], R1
  2. 相对跳转地址越界:JR类指令偏移量为8位,超出范围需用JMPA绝对跳转

五、常用命令说明

  • A 地址:从指定地址开始汇编输入程序
  • U 地址:反汇编指定地址开始的指令
  • D 地址:查看指定地址开始的内存内容
  • E 地址:修改指定地址开始的内存内容
  • G 地址:从指定地址开始运行程序
  • T 地址:从指定地址开始单步执行(跟踪进入子程序),每次执行后显示所有寄存器及状态位的值
  • R:查看当前寄存器的状态