上文计算机是怎么跑起来的?从零开始手动组装微型计算机我们说了,如何手动从来组装一台计算机,那组装完后的计算机上是怎么跑起来程序的呢?程序是如何驱动硬件工作的?
前面我们通过DMA将代码输入到内存的指定位置,然后按下REST引脚连接的开关,让CPU开始从内存第零个地址执行指令,为了能更好的理解代码的含义,我们可以以手工汇编的方式,将上面的机器语言翻译成汇编语言,Z80 CPU的使用手册中就完整的它支持的指令对于的助记词(见下图)
下表列出了本例子上的主要操作符对应的汇编语音以及执行周期数
机器语言 | 助记符 | 周期数 |
00111110 num | LD A,num | 7 |
11010011 num | OUT (num),A | 11 |
11011011 num | IN A,(num) | 11 |
11000011 num | JP num | 10 |
翻译后:
地址 机器语言
00000000 00111110 LD A,num
00000001 11001111 207
00000010 11010011 OUt(num),A
00000011 00000010 2
00000100 00111110 LD A,num
00000101 11111111 255
00000110 11010011 OUt(num),A
00000111 00000010 2
00001000 00111110 LD A,num
00001001 11001111 207
00001010 11010011 OUt(num),A
00001011 00000011 3
00001100 00111110 LD A,num
00001101 00000000 0
00001110 11010011 OUt(num),A
00001111 00000011 3
00010000 11011011 IN A,(num)
00010001 00000000 0
00010010 11010011 OUt(num),A
00010011 00000001 1
00010100 11000011 JP num
00010101 00010000 (00010000 00000000)大端序
00010110 00000000
最终汇编后的代码:
JP的操作数为什么是两个字节呢?看z80的文档:
下面解释下这段代码:
LD A,207
OUt(2),A
LD A,255
OUt(2),A
LD A,207
OUt(3),A
LD A,0
OUt(3),A
(1)先向cpu 寄存器A 写一个207,在将207写到pio的2号地址。再向寄存器A写一个255,然后将255再写到pio的2号地址;
(2)向cpu 寄存器A 写一个207,在将207写到pio的3号地址,再向寄存器A 写一个0,将0写到pio的3号地址;
最终目的也就是先后向pio的2号地址写一个207、255,3号地址写一个207、0,这是干啥呢?
2号地址在pio中是端口A的控制寄存器,3号地址是端口B的控制寄存器
为什么输入207?
根据z80 pio文档,10xx1111是控制io的代码,输入207标识要设置端口的io
out(2),207 即是设置端口A的io模式,设成每一位都1
out(3),207 即是设置端口B的io模式,设成每一位都是0
再看z80 pio文档:
mode 0就是输出模式,mode1就是输入模式,也就是:
端口A输入,端口B输出
下一段代码:
IN A,(0)
OUt(1),A
JP aaa
从读pio 0号地址的数据到cpu 寄存器A
将寄存器A的数据写入到pio的1号地址
然后再跳到IN A的代码行
也就是反复的将0号地址的数据,弄到1号地址,0号地址标识的pio的端口A数据寄存器,1号地址是B的数据寄存器,从而实现了上一节中通过改变拨测开关控制LED的亮灭。