Z80 装配程序出了问题
Z80 assembly program gone haywire
我正在开发一个小型 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
预期的结果是之后会输出"XGeneration: "和CRLF组合
例程transmitCharFromA
效果很好,输出的第一个字符确实是"X"。这是例程:
transmitCharFromA:
PUSH AF ; store char in A for later
consoleOutput:
IN A,() ; 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 (),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
例程中做错了什么:
- 打印垃圾
- 不打印 "Generation: " 消息
- 显然没有找到空终止 0x00 字符
我正在使用 z88dk assemble 并构建我的程序。
我可以在我的程序集列表中看到 LD A, (HL)
语句是 assembled 正确的,显示 消息地址的第一个字节 为LD 指令的操作数。所以我对可能出了什么问题感到困惑。
谁能指出我的错误?
您必须使用:
LD HL,generationMsg
将 generationMsg
的 地址 放入 HL,而不是像 Hans 评论的那样实际用 (generationMsg)
加载内容。
正确的程序集将显示操作码 </code> 而不是您现在获得的操作码 <code>A
。但是在任何一种情况下都会出现 generationMsg
的地址,因此不能作为区分正确性的方法。
LD HL,(generationMsg)
是一种绝对直接寻址方式的负载。您想要的指令 "loads" 是一个立即操作数,并且即使它共享相同的助记符也是完全不同的。
我正在开发一个小型 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
预期的结果是之后会输出"XGeneration: "和CRLF组合
例程transmitCharFromA
效果很好,输出的第一个字符确实是"X"。这是例程:
transmitCharFromA:
PUSH AF ; store char in A for later
consoleOutput:
IN A,() ; 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 (),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
例程中做错了什么:
- 打印垃圾
- 不打印 "Generation: " 消息
- 显然没有找到空终止 0x00 字符
我正在使用 z88dk assemble 并构建我的程序。
我可以在我的程序集列表中看到 LD A, (HL)
语句是 assembled 正确的,显示 消息地址的第一个字节 为LD 指令的操作数。所以我对可能出了什么问题感到困惑。
谁能指出我的错误?
您必须使用:
LD HL,generationMsg
将 generationMsg
的 地址 放入 HL,而不是像 Hans 评论的那样实际用 (generationMsg)
加载内容。
正确的程序集将显示操作码 </code> 而不是您现在获得的操作码 <code>A
。但是在任何一种情况下都会出现 generationMsg
的地址,因此不能作为区分正确性的方法。
LD HL,(generationMsg)
是一种绝对直接寻址方式的负载。您想要的指令 "loads" 是一个立即操作数,并且即使它共享相同的助记符也是完全不同的。