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

推荐订阅源

Google DeepMind News
Google DeepMind News
S
Security Affairs
阮一峰的网络日志
阮一峰的网络日志
L
LangChain Blog
Microsoft Azure Blog
Microsoft Azure Blog
雷峰网
雷峰网
Recent Announcements
Recent Announcements
WordPress大学
WordPress大学
The GitHub Blog
The GitHub Blog
博客园_首页
The Cloudflare Blog
M
MIT News - Artificial intelligence
博客园 - 【当耐特】
MyScale Blog
MyScale Blog
S
SegmentFault 最新的问题
P
Proofpoint News Feed
Y
Y Combinator Blog
Jina AI
Jina AI
博客园 - 聂微东
A
About on SuperTechFans
Blog — PlanetScale
Blog — PlanetScale
博客园 - 司徒正美
G
Google Developers Blog
云风的 BLOG
云风的 BLOG
F
Full Disclosure
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
Microsoft Security Blog
Microsoft Security Blog
爱范儿
爱范儿
T
Tailwind CSS Blog
J
Java Code Geeks
Vercel News
Vercel News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Stack Overflow Blog
Stack Overflow Blog
罗磊的独立博客
小众软件
小众软件
酷 壳 – CoolShell
酷 壳 – CoolShell
T
The Blog of Author Tim Ferriss
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
博客园 - 三生石上(FineUI控件)
W
WeLiveSecurity
PCI Perspectives
PCI Perspectives
Attack and Defense Labs
Attack and Defense Labs
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
宝玉的分享
宝玉的分享
IT之家
IT之家
Hacker News: Ask HN
Hacker News: Ask HN
The Register - Security
The Register - Security
T
The Exploit Database - CXSecurity.com
T
Threat Research - Cisco Blogs

Yesterday17's Blog

2026 新年解密红包 / Melody Flag | Yesterday17's Blog 谈谈 Iori 的设计思路(二):如何实现一个 Showroom 录制工具? | Yesterday17's Blog 谈谈 Iori 的设计思路(一):从 Nico Timeshift 说起 | Yesterday17's Blog Iori Minyami 0.1.0 发布 | Yesterday17's Blog 2025 新年解密红包 / Melody Flag | Yesterday17's Blog 使用 Cloudflare Warp 解决罗森票务的海外登录问题 | Yesterday17's Blog How To Blog 04: The Astro v5 Era | Yesterday17's Blog 谈谈 tokio::select! 的公平性 | Yesterday17's Blog Learning Pingora 05 - Connect with TLS | Yesterday17's Blog Leaving Bytedance | Yesterday17's Blog 大橋彩香 AsiaTour「Reflection」上海公演 个人向记录 & Repo | Yesterday17's Blog Recoving from burnout - What happened? | Yesterday17 Yubikey 重建手册 | Yesterday17's Blog How To Blog 03: Heimus | Yesterday17's Blog 🪧 Blog Migration Accouncement | Yesterday17's Blog Learn Your IDE - VSCode 是如何仅重启插件的? | Yesterday17's Blog How To Blog 02: Astro❤️Password | Yesterday17's Blog How To Blog 01: Why, How, and the Future | Yesterday17's Blog Learning Pingora 04 - Establish L4 Connection | Yesterday17's Blog Learning Pingora 03 - Upstreams and Peers | Yesterday17's Blog Learning Pingora 02 - A Simple HTTP Server | Yesterday17's Blog Learning Pingora 01 - Getting Started | Yesterday17's Blog 2024 新年解密红包 / Melody Flag | Yesterday17's Blog 向新的一年飞驰——记录 2023 | Yesterday17's Blog 「サクラノ刻」对话选摘(2) | Yesterday17's Blog PGP Key Revocation 注销声明 | Yesterday17's Blog 「サクラノ刻」对话选摘(1) | Yesterday17's Blog 2023 新年解密红包 / Melody Flag | Yesterday17's Blog 『蒼の彼方のフォーリズム』通关感想 | Yesterday17's Blog 单显卡直通教程 | Yesterday17's Blog 对博客与笔记的思考 | Yesterday17's Blog Project Anni 之旅(3)自动化 Flutter 应用 CI/CD 上架流程 | Yesterday17's Blog AsobiStage 直接播放链接 | Yesterday17 如何在后分P时代进行投稿——sswa使用详解 | Yesterday17's Blog JSON RPC 与 LSP 协议基础 | Yesterday17's Blog Grajapa Shueisha / BookEnd 加密方式调查 | Yesterday17's Blog 【2022篇+WriteUp】如何再收一个新年红包? | Yesterday17's Blog 如何将良心云的良心功能清理干净 | Yesterday17's Blog 【油猴脚本】bilibili 投稿页面返回旧版+旧版页面强制允许分P上传 | Yesterday17's Blog Cloudr1v1 授权方式分析 | Yesterday17 Typora 1.0.2 逆向实录 | Yesterday17's Blog Project Anni 之旅(2)ValueAfterTable——toml-rs的实现与限制 | Yesterday17's Blog IPv4透明代理+IPv6 Passthrough——树莓派单臂软路由折腾记 | Yesterday17's Blog Chaos; Child 汉化补丁 神秘编码探索 | Yesterday17's Blog 镣铐与舞蹈——个性与共性之迷思 | Yesterday17's Blog Go 学习笔记 02 - 找准 io 之道 | Yesterday17's Blog NAT Slipstreaming v1 原理浅析 | Yesterday17's Blog 绕过「9-nine-」的 CDKEY 验证——KrkrPlugin 正(?)向实录 | Yesterday17's Blog 静流的青春纪念册——「サクラノ刻 -櫻の森の下を歩む-」体验版感言 | Yesterday17's Blog Project Anni 之旅 01 - 从 clap-builder 到 derive | Yesterday17's Blog [Google CTF 2021] CPP WriteUp | Yesterday17's Blog 获取 アソビステージ 的实际播放链接 | Yesterday17's Blog 90 行 Rust 代码实现 AsyncTeeReader | Yesterday17's Blog 或许还算有价值一读的文章列表 | Yesterday17's Blog 从零开始的 Seedbox 之旅 | Yesterday17's Blog [随笔]技术型博客行文迷思(1) | Yesterday17's Blog 浅谈 git fetch 的工作方式 | Yesterday17's Blog 『ソーサレス*アライヴ! ~the World's End Fallen Star~』通关感想" | Yesterday17's Blog Rust std::fmt 格式语法简述 | Yesterday17's Blog 日亚修改居住国的解决方案 | Yesterday17's Blog [Windows/Linux] GC553 的 Switch 完美采集之路 | Yesterday17's Blog 【翻译】Subtyping and Variance / 子类型与变型 | Yesterday17's Blog Berd's Red Envelope 2021 WriteUp | Yesterday17's Blog 【中英对照】ALSA 音频 API 使用教程/A Tutorial on Using the ALSA Audio API | Yesterday17's Blog 从 cue_scanner.l 看 CUE Sheet 的词法单元 | Yesterday17's Blog Postman 历史记录导出的解决方案 | Yesterday17's Blog 《恋爱绮谭 不存在的夏天》通关感想 | Yesterday17's Blog [微机实验/TD-PITE] 微机接口综合实验 | Yesterday17's Blog [微机实验/TD-PITE] 数码管显示实验 | Yesterday17's Blog Airsonic Advanced+Google Drive+Caddy 部署纪实 | Yesterday17's Blog X-NUCA 2020 - hellowasm 题解 | Yesterday17's Blog [微机实验/TD-PITE] 8251 串行接口实验 | Yesterday17's Blog Node.js child_process.fork 与 env 污染 RCE | Yesterday17's Blog EP.01 「夜の向日葵」 | Yesterday17's Blog [微机实验/TD-PITE] 8254 定时/计数器实验+选做实验 | Yesterday17's Blog [JLU CTF/2020] babywasm WriteUp | Yesterday17's Blog PHP 反序列化与经典利用 | Yesterday17's Blog WebAssembly 逆向简述 | Yesterday17's Blog 『彼女、お借りします』一期完结点评 | Yesterday17's Blog [微机实验/TD-PITE] D/A 转换实验+选做实验 | Yesterday17's Blog [微机实验/TD-PITE] A/D 转换实验+选做实验 | Yesterday17's Blog 开源项目申请 JetBrains Open Source License 简单流程 | Yesterday17's Blog 微软拼音与 JetBrains 搜索快捷键冲突的解决方案 | Yesterday17's Blog [微机实验/TD-PITE] 8259 中断优先级实验+选做实验 | Yesterday17's Blog IFTTT 测试(续) | Yesterday17 IFTTT 测试 | Yesterday17's Blog [微机实验/TD-PITE] 存储器扩展实验+选做实验 | Yesterday17's Blog 新版 GCC 针对 -fdump-translation-unit 的替代方案 | Yesterday17's Blog 一次 HSTS 策略配置的排错之旅 | Yesterday17's Blog YukiNative 踩坑记——Windows 的消息队列 | Yesterday17's Blog 我是我自己——论获取 HTTPS 证书时的验证步骤 | Yesterday17's Blog 【设计文档】对 PUG 的大规模设计修订(1.1) | Yesterday17's Blog GS65 折腾记(2)加装固态,分区,Grub2 引导 Manjaro LiveCD | Yesterday17's Blog 「さくら、もゆ。」的空白字体列表——一次逆向问题定位过程实录 | Yesterday17's Blog GSuite 探索篇(1)使用 Service Account 向 Google Drive 传输文件 | Yesterday17's Blog 『サクラノ詩 -櫻の森の上を舞う-』通关感想 | Yesterday17's Blog 《ATRI -My Dear Moments-》通关感想 | Yesterday17's Blog [工具][VSCode 扩展] AegiKit——方便 Aegisub 使用的工具箱 | Yesterday17's Blog 贝塞尔曲线、字体矢量化与曲线运算 | Yesterday17's Blog NAT 类型初探 | Yesterday17's Blog
[微机实验/TD-PITE] 键盘扫描及数码管显示实验 | Yesterday17's Blog
Yesterday17 · 2020-11-16 · via Yesterday17's Blog

ToC

  • 实验内容
  • 实验接线
  • 代码
  • 选做实验
    • 说明
    • 效果
    • 代码

实验内容

在数码管上显示键盘输入的内容,新输入的内容显示在数码管的最右侧。

当数码管显示空间已满时,删除最左侧的文本。

实验接线

这次的接线和上次是一样的。唯一的不同是不能不连 Y1-Y4 了(笑)

代码

A8255 EQU 0600H

B8255 EQU 0602H

C8255 EQU 0604H

CON8255 EQU 0606H

ROWOUT EQU 200H

SSEG SEGMENT STACK

DW 20 DUP(?)

SSEG ENDS

DATA SEGMENT

TBL:

DB 3FH ;; 0

DB 06H ;; 1

DB 5BH ;; 2

DB 4FH ;; 3

DB 66H ;; 4

DB 6DH ;; 5

DB 7DH ;; 6

DB 07H ;; 7

DB 7FH ;; 8

DB 6FH ;; 9

DB 77H ;; A

DB 7CH ;; B

DB 39H ;; C

DB 5EH ;; D

DB 79H ;; E

DB 71H ;; F

SEQ:

DB 00011111B ;; POS 0

DB 00101111B ;; POS 1

DB 00110111B ;; POS 2

DB 00111011B ;; POS 3

DB 00111101B ;; POS 4

DB 00111110B ;; POS 5

VAL:

DB 6 DUP(0)

VAL_USED:

DB 6 DUP(0)

VAL_HEAD DW 0005H

DATA ENDS

CODE SEGMENT

ASSUME CS:CODE, DS:DATA, SS:SSEG

START PROC

MOV AX, DATA

MOV DS, AX

MOV AL, 81H ;;10001001B ;; A B OUT, C IN

MOV DX, CON8255

OUT DX, AL

MOV AX, 0000H

LO:

CALL VAL_DISPLAY

CALL SCAN

CMP AX, 10H

JE LO

CALL VAL_INSERT

WAIT_UP:

CALL VAL_DISPLAY

CALL KEY_PRESSED

CMP AX, 1

JE WAIT_UP

JMP LO

MOV AX, 4C00H

INT 21H

START ENDP

SCAN PROC

BEGIN:

CALL KEY_PRESSED ;; EXIT IF NOT PRESSED

CMP AX, 0

JE SCAN_NO_KEY

CALL DELAY

CALL KEY_PRESSED

CMP AX, 0

JE SCAN_NO_KEY

MOV CH, 0FEH

MOV CL, 0

COLUMN:

MOV AL, CH

MOV DX, A8255

OUT DX, AL

MOV DX, C8255

IN AL, DX

L1:

TEST AL, 1

JNZ L2

MOV AL, 00H

JMP KCODE

L2:

TEST AL, 2

JNZ L3

MOV AL, 04H

JMP KCODE

L3:

TEST AL, 4

JNZ L4

MOV AL, 08H

JMP KCODE

L4:

TEST AL, 8

JNZ NEXT

MOV AL, 0CH

KCODE:

ADD AL, CL

JMP SCAN_FIN

NEXT:

INC CL

MOV AL, CH

TEST AL, 08H

JE SCAN_NO_KEY

ROL AL, 1

MOV CH, AL

JMP COLUMN

SCAN_NO_KEY:

MOV AX, 10H

SCAN_FIN:

RET

SCAN ENDP

;; RETURN WHETHER KEY PRESSED IN AX

KEY_PRESSED PROC

MOV DX, A8255

MOV AL, 00H

OUT DX, AL ;; LINE OUTPUT 0000

MOV DX, C8255

IN AL, DX ;; GET LINE STATUS

AND AL, 0FH

CMP AL, 0FH

JE KP_NONE

MOV AX, 1 ;; KEY PRESSED

RET

KP_NONE:

MOV AX, 0

RET

KEY_PRESSED ENDP

;; INSERT AX TO VAL[VAL_HEAD]

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; INDEX: 0 1 2 3 4 5

;; VALUE: A B C D E F

;; HEAD: |

;; INPUT: 0

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; INDEX: 0 1 2 3 4 5

;; VALUE: 0 B C D E F

;; HEAD: |

;; (-> 1 BYTE)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

VAL_INSERT PROC

PUSH BX

LEA BX, VAL

MOV SI, VAL_HEAD

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; !!!CAUTION!!! ;;

;; MAKE SURE TO USE 8-BIT REGISTER ;;

;; IF YOU WANT TO MOVE BYTES ;;

;; BETWEEN MEMORY AND REGISTER!! ;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

MOV [BX+SI], AL ;; NUMBER BYTE

MOV DL, 1

MOV [BX+SI+6], DL ;; DISPLAY BYTE

INC SI

CMP SI, 5 ;; HEAD <= 5, SKIP

JLE VI_EXIT

SUB SI, 6 ;; MAKE HEAD IN [0, 5]

VI_EXIT:

MOV VAL_HEAD, SI

POP BX

RET

VAL_INSERT ENDP

;; DISPLAY VAL ARRAY

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; INDEX: 0 1 2 3 4 5

;; VALUE: A B C D E F

;; HEAD: |

;; THIS IS THE SAME DIRECTION AS SCREEN

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

VAL_DISPLAY PROC

PUSH CX

MOV CX, 6

LEA BX, VAL

MOV SI, VAL_HEAD

VD_LO:

PUSH CX

MOV AH, [BX+SI]

MOV AL, CL

DEC AL

MOV DH, [BX+SI+6]

CMP DH, 0

JE VD_SKIP_BIT

PUSH BX

PUSH SI

CALL PUT

CALL DELAY

POP SI

POP BX

VD_SKIP_BIT:

POP CX

;; CALCULATE NEXT SI

INC SI

CMP SI, 5 ;; HEAD <= 5, SKIP

JLE VD_SI_SKIP

SUB SI, 6

VD_SI_SKIP:

LOOP VD_LO

POP CX

RET

VAL_DISPLAY ENDP

;; NUM: AH

;; POS: AL

PUT PROC

PUSH AX

;; SELECT POS

LEA BX, SEQ

PUSH AX

MOV AH, 0

MOV SI, AX

;; OUTPUT POS

MOV DX, A8255

MOV AL, [BX+SI]

OUT DX, AL

POP AX

;; SELECT NUM

LEA BX, TBL

MOV AL, AH

MOV AH, 0

MOV SI, AX

;; OUTPUT DATA

MOV DX, B8255

MOV AL, [BX+SI]

OUT DX, AL

POP AX

RET

PUT ENDP

DELAY PROC

MOV CX, 0FFH

LOOP $

RET

DELAY ENDP

CODE ENDS

END START

选做实验

说明

通过键盘输入 0-E,将刚刚输入的一位数字显示在数码管上。

最开始数码管无显示。在输入新数字后,将输入的数字显示在数码管最右端。之后每次输入数字,数字的显示位置向左移动一格。

当显示的数字已经位于最左时,此时输入的数字并不立即向右移动,而是先在最左停顿一次,下一个输入的数字再向右移动。

到达最右时的处理和最左一致。

键盘输入 F 时程序退出。

效果

上面说的这段话简直就不是人话,还是看一下实际的效果吧(

代码

A8255 EQU 0600H

B8255 EQU 0602H

C8255 EQU 0604H

CON8255 EQU 0606H

ROWOUT EQU 200H

SSEG SEGMENT STACK

DW 20 DUP(?)

SSEG ENDS

DATA SEGMENT

TBL:

DB 3FH ;; 0

DB 06H ;; 1

DB 5BH ;; 2

DB 4FH ;; 3

DB 66H ;; 4

DB 6DH ;; 5

DB 7DH ;; 6

DB 07H ;; 7

DB 7FH ;; 8

DB 6FH ;; 9

DB 77H ;; A

DB 7CH ;; B

DB 39H ;; C

DB 5EH ;; D

DB 79H ;; E

DB 71H ;; F

DB 00H ;; CLR

SEQ:

DB 00011111B ;; POS 0

DB 00101111B ;; POS 1

DB 00110111B ;; POS 2

DB 00111011B ;; POS 3

DB 00111101B ;; POS 4

DB 00111110B ;; POS 5

VAL DB 00H

VAL_POS DB 00H

VAL_SHOW DB 00H

VAL_STEP DB 00H

DATA ENDS

CODE SEGMENT

ASSUME CS:CODE, DS:DATA, SS:SSEG

START PROC

MOV AX, DATA

MOV DS, AX

MOV AL, 81H ;;10001001B ;; A B OUT, C IN

MOV DX, CON8255

OUT DX, AL

MOV AX, 0000H

LO:

CALL NUM_DISPLAY

CALL SCAN

CMP AX, 10H

JE LO

CMP AX, 0FH

JE MA_EXIT

CALL NUM_SET

WAIT_UP:

CALL NUM_DISPLAY

CALL KEY_PRESSED

CMP AX, 1

JE WAIT_UP

JMP LO

MA_EXIT:

MOV AX, 1000H

CALL PUT

MOV AX, 4C00H

INT 21H

START ENDP

SCAN PROC

BEGIN:

CALL KEY_PRESSED ;; EXIT IF NOT PRESSED

CMP AX, 0

JE SCAN_NO_KEY

CALL DELAY

CALL KEY_PRESSED

CMP AX, 0

JE SCAN_NO_KEY

MOV CH, 0FEH

MOV CL, 0

COLUMN:

MOV AL, CH

MOV DX, A8255

OUT DX, AL

MOV DX, C8255

IN AL, DX

L1:

TEST AL, 1

JNZ L2

MOV AL, 00H

JMP KCODE

L2:

TEST AL, 2

JNZ L3

MOV AL, 04H

JMP KCODE

L3:

TEST AL, 4

JNZ L4

MOV AL, 08H

JMP KCODE

L4:

TEST AL, 8

JNZ NEXT

MOV AL, 0CH

KCODE:

ADD AL, CL

JMP SCAN_FIN

NEXT:

INC CL

MOV AL, CH

TEST AL, 08H

JE SCAN_NO_KEY

ROL AL, 1

MOV CH, AL

JMP COLUMN

SCAN_NO_KEY:

MOV AX, 10H

SCAN_FIN:

RET

SCAN ENDP

;; RETURN WHETHER KEY PRESSED IN AX

KEY_PRESSED PROC

MOV DX, A8255

MOV AL, 00H

OUT DX, AL ;; LINE OUTPUT 0000

MOV DX, C8255

IN AL, DX ;; GET LINE STATUS

AND AL, 0FH

CMP AL, 0FH

JE KP_NONE

MOV AX, 1 ;; KEY PRESSED

RET

KP_NONE:

MOV AX, 0

RET

KEY_PRESSED ENDP

;; SET AL TO VAL & MOVE POS

NUM_SET PROC

PUSH AX

MOV VAL, AL

MOV AL, VAL_POS

ADD AL, VAL_STEP

CMP VAL_STEP, 0 ;; REGULAR STATUS: STEP != 0

JNE NS_REG

CMP VAL_POS, 5

JE NS_LMOST

MOV VAL_STEP, 1 ;; POS == 0, RIGHT MOST

JMP NS_FIN

NS_LMOST: ;; POS == 5, LEFT MOST

MOV VAL_STEP, -1

JMP NS_FIN

NS_REG:

CMP AL, 5

JE NS_SET0

CMP AL, 0

JE NS_SET0

JMP NS_FIN

NS_SET0:

MOV VAL_STEP, 0

NS_FIN:

MOV VAL_SHOW, 1

MOV VAL_POS, AL

POP AX

RET

NUM_SET ENDP

;; DISPLAY VAL AT VAL_POS

NUM_DISPLAY PROC

;MOV AL, VAL_SHOW

CMP VAL_SHOW, 0

JE ND_SKIP

MOV AH, VAL

MOV AL, VAL_POS

CALL PUT

CALL DELAY

ND_SKIP:

RET

NUM_DISPLAY ENDP

;; NUM: AH

;; POS: AL

PUT PROC

PUSH AX

;; SELECT POS

LEA BX, SEQ

PUSH AX

MOV AH, 0

MOV SI, AX

;; OUTPUT POS

MOV DX, A8255

MOV AL, [BX+SI]

OUT DX, AL

POP AX

;; SELECT NUM

LEA BX, TBL

MOV AL, AH

MOV AH, 0

MOV SI, AX

;; OUTPUT DATA

MOV DX, B8255

MOV AL, [BX+SI]

OUT DX, AL

POP AX

RET

PUT ENDP

DELAY PROC

MOV CX, 0FFH

LOOP $

RET

DELAY ENDP

CODE ENDS

END START