我是一名学习计算机科学的新生。在计算机工程领域,我们正在研究Zilog Z80 8位微处理器(1MHz)以及需要使用面包板和电缆手动连接的一组组件。
连接部分并不令我担心,但是我确实有一些有关组装程序的问题,我需要编写这些程序才能使程序正常工作(LED运行灯,需要手动输入行为和频率)。
我已经阅读了该手册,并且知道可以使用的说明集(仅是必需品)。首先,我并不是在尝试获得最干净,最漂亮的代码;但请放心,由于我喜欢简洁高效的代码,因此稍后会进行美化。
目前,该程序似乎在模拟器中运行良好,因此语法似乎还不错。不过,我不确定如何解决某些逻辑问题。
该练习具有以下规格:
我使用ORG E000h
设置了起始地址,并使用MOV SP,FFFFh
初始化了堆栈指针。对于输入(三种不同类型的闪烁/运行以及两种不同的频率,总共等于五个按钮),我创建了不同的标签。
目前,我的问题是我不太确定如何正确地输入物理数据-IIRC,我需要通过使用XOR来指定位模式,将所有东西都设为1,但所需的输入,以便可以使用我程序中的信息。
但是,即使我确实知道它的工作方式(至少我认为我知道),但我仍无法完全围绕软件实现进行思考。另外,我遇到以下问题:按一个开关将闪烁频率更改为1/4 Hz,而按另一个开关将其更改为4Hz。在高级语言中,我只是在这里使用IF / ELSE,但在这种情况下我不知道如何做-遗憾的是,该手册仅包含基本操作,所以我很茫然。
因此,我想我会碰运气并向社区寻求帮助。
对于那些感兴趣的人,我将发布我的代码。正如我已经提到的,这是非常基本的,但是我只需要它就可以暂时完成工作。由于我不喜欢笨拙的格式代码,因此我发布了文件here。该文件是通过GoogleDrive托管的* .txt。
感谢您的时间,祝您愉快!
[EDIT]根据用户Ruud Helderman的输入在帖子中添加了特定代码
[。edit]更新了* .txt文件中的代码-现在更简单,更有效
[EDIT]使用HTML格式突出显示帖子中的指令
特定代码段:
blink: ;function: all LED blinking, activated via input[2]
MOV A,FFh
OUT 05h,A ;all LED out
CALL pause1 ;frequency 1/4Hz, activated via input[5]
MOV A,00h
OUT 05h,A ;all LED on
CALL pause1
JP blink ;jump back to begin of function
上面的功能使用输入开关板上的不同特定物理开关来改变LED的行为(在这种情况下:闪烁)并改变频率,总共有8个开关(1到8,无效状态= 1;使用了开关2到6) 。我知道获得输入应该是小菜一碟,应该只使用位模式为0且正好为1的XOR。
在尝试解决问题时,我遇到了多种在线方法,例如使用TEST
检查特定位置的位。不过,我的说明手册中没有提到任何此类指令,作业本身也没有提及。
我很清楚这可能是一个微不足道的问题,也许我只是陷入了通过过度思考而建立自己的心理循环中,但此刻我不知道该如何去做(即使我能看到地平线上的城堡-感谢卡夫卡!)。
非常感谢您的帮助。
答案 0 :(得分:2)
首先,如果使用MOV
,则可能使用的是8080语法而不是Z80语法。出于历史上的法律原因,Z80不仅扩展了8080的汇编语言,而且还重命名了所有现有的助记符(例如,将MOV
更改为LD
)。如果您正在搜索Z80代码并找到您不认识的说明,则可能是其中一部分。
实现if / else类型条件的通常方法是:
根据您的情况,您想执行某项操作还是不执行某项操作,取决于是否设置了某位,因此一种执行此操作的方法是ANI
(z80:AND
)。它计算累加器和一个操作数的逻辑和,并将其存储在累加器中,但除此之外,它还会设置零标志。因此,您可以根据是否设置了某位,使用JNZ
(/ JP NZ
)和JZ
(/ JP Z
)来执行某些操作。例如
; upon entry, A has an unknown value, loaded from somewhere.
ANI 08h ; Set a = a & 8; so either bit 2 was originally set and a now
; has the value 8, or bit 2 wasn't set and a now has the value 0.
; Also: the zero flag is now set if a is zero, reset otherwise.
; So you've loaded NOT (a.bit2) into the zero flag.
; You've also lost the rest of the accumulator, but such is life.
; Keep a copy somewhere, or grab it again via IN as required.
JZ bitnotset
; code here will be performed only if bit 2 was originally unset.
bitnotset:
; this code will happen regardless of whether bit 2 was set.
我不知道8080或Z80风格的语法中的TEST
。
您可能还会看到破坏性较小且效率稍高的解决方案,该解决方案通过将字节中的多个位移入进位来依次测试它们。这是另一种选择,但不一定值得担心,除非您的课程笔记强烈暗示这是您应该寻找的方向。
答案 1 :(得分:0)
经过几天的思考和思考,在大家的大力支持下,我终于找到了解决问题的方法。最后,我最担心的是我不知道如何正确检查输入。
正如我所假设的,问题出在我被误解的困扰,所幸我的实验室合作伙伴纠正了这个误解。因此,毕竟,我们能够使我们的程序能够正常工作-在最后一分钟而不是100%正常运行,但是它可以正常工作并满足要求。
那我的误解是什么?有趣的是,我知道我们必须去的地方,而且这个想法是正确的。问题是我跳过了逻辑运算的主要部分-我已经在脑海中进行了计算,然后将实际的工作解决方案与过时的AND
结合使用,从而破坏了功能。
总而言之,XOR
和AND
的正确组合如下:
programloop:
MOV A,40h ;state of button 2, inverted (XOR FFh)
MOV B,A ;save state to register B
IN A,03h ;input at port-address 03h
AND B ;find out if button is pressed
JPNZ blink ;if yes, jump to blink
MOV A,20h ;state of button 3, inverted (XOR FFh)
MOV B,A ;save state to register B
IN A,03h ;input at port-address 03h
AND B ;find out if button is pressed
JPNZ goright ;if yes, jump to goright
MOV A,10h ;state of button 4, inverted (XOR FFh)
MOV B,A ;save state to register B
IN A,03h ;input at port-address 03h
AND B ;find out if button is pressed
JPNZ goleft ;if yes, jump to goleft
JP programloop ;go back to beginning (input has to be checked constantly)
这涉及到三个按钮,这些按钮改变了LED的行为。
关于频率,由于时间紧迫,我们不得不将复杂性降低到仅两个状态(我们错误地理解了分配,并错误地从奖金问题开始,这花了我们大约50%的开发时间-是的。学到的:始终从顶部开始阅读,仔细阅读。)
但是由于频率改变有效,所以结果很好。
MOV A,03h ;state of button five being pressed (inverted)
MOV B,A ;saved state into register B for later use
IN A,03h ;physical input over button
AND B ;find out if button is pressed
JPNZ freq025Hz ;if yes, jump to freq025Hz
JPZ freq4Hz ;if no, jump to freq4Hz
就这样!
再次感谢大家的帮助。
如果还有任何疑问,请随时提问!