我正在研究一个小的Z80组装程序,这是我的第一个程序。这是我的Z-80汇编代码:
main:
LD SP, $FFFF ; start by setting stack to top of RAM
printChar1:
LD A, 'X' ; this works
CALL transmitCharFromA ; this works
LD HL, (generationMsg) ; this does not work
CALL txAsciiZMsg ; this does not work
endInNopLoop:
NOP
JR endInNopLoop
generationMsg: DEFB "Generation: ", CR, LF, 0 ; null-terminated string
预期结果是它将随后输出带有CRLF组合的“ XGeneration:”。
例程transmitCharFromA
很好用,输出的第一个字符确实是“ X”。这是例程:
transmitCharFromA:
PUSH AF ; store char in A for later
consoleOutput:
IN A,($80) ; read ACIA status byte
BIT 1,A ; set Z flag if still transmitting character
JR Z,consoleOutput ; and loop until flag signals ready
POP AF ; get the character back from the stack
OUT ($81),A ; send it over RS232 to ACIA outpout address
RET
正如我提到的,这很好用。因此,我想通过启用以null终止的字符串的输出为基础:
txAsciiZMsg:
LD A, (HL) ; A holds pointer to start of null-term string
OR A ; OR A with A to set Z flag if A holds null terminator
RET Z ; return if done
CALL transmitCharFromA ; otherwise transmit it using working routine
INC HL ; move pointer to next character
JR txAsciiZMsg ; and keep going
这不起作用,输出一堆垃圾字符,然后停止并(显然)进入endInNopLoop
循环。
任何人都可以在txAsciiZMsg
例程中提示我做错了什么吗
我正在使用z88dk组装和构建程序。
我可以在程序集列表中看到LD A, (HL)
语句已正确汇编,显示了消息地址的第一个字节作为LD指令的操作数。因此,我对可能出问题的地方感到困惑。
有人可以指出我的错误吗?
答案 0 :(得分:5)
您必须使用:
LD HL,generationMsg
将generationMsg
的地址放入HL,而不是像Hans所说的那样用(generationMsg)
实际加载内容。
正确的程序集将显示操作码$21
,而不是您现在得到的操作码$2A
。但是无论哪种情况,generationMsg
的地址都会出现,因此不会用作区分正确性的方法。
LD HL,(generationMsg)
是具有绝对直接寻址模式的负载。您想要的指令“装载”一个立即操作数,即使共享相同的助记符,也完全不同。