3.3 Z80 CPU的寄存器结构
这里先稍微复习一下第2章的内容。计算机的硬件有三个基本要素,CPU、内存和I/O。CPU负责解释、执行程序,从内存或I/O输入数据,在内部进行运算,再把运算结果输出到内存或I/O。内存中存放着程序,程序是指令和数据的集合。I/O中临时存放着用于与周边设备进行输入输出的数据
复习就到这里,下面来扩充所学到的知识。既然数据的运算是在CPU中进行的,那么在CPU内部就应该有存储数据的地方。这种存储数据的地方叫做“寄存器”。虽然也叫寄存器,但是与I/O的寄存器不同,CPU的寄存器不仅能存储数据,还具备对数据进行运算的能力。CPU带有什么样的寄存器取决于CPU的种类。Z80 CPU所带有的寄存器如图3.2所示(A,B,C,D,E,F,H,L每个寄存器都带有一个辅助寄存器,本节忽略了对它们的介绍)
图3.2 Z80 CPU的寄存器
A、B、C、D等字母是寄存器的名字。在汇编语言中,可以将寄存器的名字指定为操作数
IX,IY,SP,PC这4个寄存器的大小是16比特,其余寄存器大小都是8比特。寄存器的用途取决于它的类型,有的指令只能将特定的寄存器指定为操作数
举例来说,A寄存器也叫做“累加器”,是运算的核心。所以连接到它上面的导线也一定会比其他寄存器多。F寄存器也叫做“标志寄存器”,用于存储运算结果的状态,比如是否发生了进位、数字大小的比较结果等。PC寄存器也叫做“程序指针”,存储着指向CPU接下来要执行的指令的地址。PC寄存器的值会随着滴答滴答的时钟信号自动更新,可以说程序就是依靠不断变化的PC寄存器的值运行起来的。SP寄存器也叫做“栈顶指针”,用于在内存中创建一块称为“栈”的临时数据存储区域
既然已经熟悉了寄存器的功能,下面就开始介绍代码清单3.2的内容。这段程序大体上可以分为两部分 – “设定Z80 PIO”和“与Z80 PIO进行输入输出”。Z80 PIO带有两个端口(端口A和端口B),用于与周边设备输入输出数据。首先必须为每个端口设定输入输出模式,这里端口A用于接收由指拨开关输入的数据,为了实现这个功能,需要如下的代码
LD A,207
OUT (2),A
LD A,255
OUT (2),A
这里的207和255是连续向Z80 PIO的端口A控制寄存器(对应该I/O的地址编号为2)写入的两个数据。虽然使用OUT指令可以向I/O写入数据,但不能直接把207和255这样的数字作为OUT指令的操作数,操作数必须是已存储在CPU寄存器中的数字,这是汇编语言的规定。
于是,先通过指令LD A 207把数字207读入到寄存器A中,再通过指令OUT (2),A把寄存器A中的数据写入到I/O地址所对应的寄存器中。像(2)这样用括号括起来的数字,表示的地址编号,端口A控制寄存器的I/O地址是2号
一旦把207写入到端口A控制寄存器,Z80 PIO就明白了“哦,想要设定端口A的输入输出模式啊!”而通过接下来写入的255,Z80 PIO就知道“要把端口A设定为输入模式”
同样地,通过下面的程序可以将端口B设定为输出模式
LD A,207
OUT (3),A
LD A,0
OUT (3),A
先把207写入端口B控制寄存器(对应的I/O地址为3号)然后写入0,这个0表示要把端口B设定为输出模式,应该使用什么样的数字设定端口,在Z80 PIO的资料上有说明。用207,255,0这样的数字表示功能设定参数,这也是为了适应计算机的处理方式
完成了Z80 PIO的设定后,就进入了一段死循环处理,用于把由指拨开关输入的数据输出到LED。为了完成这个功能,需要如下的代码:
LOOP: IN A,(0)
OUT (1),A
JP LOOP
IN A,(0)的作用是把数据由端口A数据寄存器(连接在指拨开关上,对应的I/O地址为0号)输入到CPU的寄存器A
OUT (1),A的作用是把寄存器A的值输出到端口B数据寄存器上(连接在LED上,对应的I/O地址为1号)
JP LOOP的作用是使程序的流程跳转到LOOP(标签名)标签所标识的指令上。JP是Jump的缩写
IN A,(0)所在行的开头有一个标签LOOP:,代表着这一行的内存地址。正如刚才所讲的那样,在用汇编语言编程时,如果老想着“这一行对应的内存地址是什么?“就会很不方便,所以就要用LOOP:这样的标签代替内存地址。当把标签作为JP指令的操作数时,标签名的结尾不需要冒号,但在设定标签时,标签名的结尾需要加一个冒号,这一点请注意
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论