我正在编写一个程序(在PEP9程序集中),该程序应该在开始时输出-1
,然后以小写ASCII字符作为输入,将其转换为大写并输出。
到目前为止,我有:
LDWA 0xFFFF, i
DECO 0xFFFF, i
LDBA 0xFC15, d
STWA 0x001D, d
STBA 0xFC16, d
LDWA 0x001D, d
SUBA 0x001F, d
ORA 0x0021, d
STBA 0xFC16, d
STOP
.BLOCK 2
.WORD 20
.WORD 0x0020
.END
[无论何时使用输入运行它,它都会加20h而不是减20h来使ASCII字符变为大写。有指针吗?
使用地址(和一些注释)重新填充代码可以使发现潜在问题更加容易:
0000 LDWA 0xFFFF, i ; set A to -1, why?
0003 DECO 0xFFFF, i ; decimal output -1
0006 LDBA 0xFC15, d ; get input character
0009 STWA 0x001D, d ; store to variable
000c STBA 0xFC16, d ; output character
000f LDWA 0x001D, d ; get character back
0012 SUBA 0x001F, d ; presumably subtract 0x20
0015 ORA 0x0021, d ; not sure what this intends
0018 STBA 0xFC16, d
001b STOP ; 1-byte operation
001c .BLOCK 2 ; two arbitrary bytes.
001e .WORD 20 ; takes two bytes 0x0014
0020 .WORD 0x0020 ; 0x0020
.END
基于此,您似乎使用了错误的地址进行直接存储和检索,可能是因为您认为STOP
是两个字节的操作,但我不确定。
向前,您应该能够摆脱多余的代码,并通过仅作用于范围(含)在内来确保仅使用大写小写字母a..z
。这样的事情将是一个好的开始:
asc_a: .equate 0x0061 ; Lower case A.
asc_z: .equate 0x007a ; Lower case Z.
sub_val: .equate 0x0020 ; Difference from upper to lower.
in_char: .equate 0xfc15 ; Address to get char from user.
out_char: .equate 0xfc16 ; Address to put char to user.
main: deco 0xffff,i ; Decimal output -1.
ldba in_char,d ; Get input character.
cpwa asc_a,i ; If outside a..z, do not translate.
brlt no_xlat
cpwa asc_z,i
brgt no_xlat
suba sub_val,i ; Convert to upper case.
no_xlat: stba out_char,d ; Output character.
stop
[您将在这里看到实际上并不需要[[ne]]数据存储,因为我们可以将立即数用于常量,将累加器用于字符。 do
如果您0000 start: br main
0003 some_data: .block 0x20
0023 more_data: .word 0xdead
0026 more_data: .word 0xbeef
0029 main: <<Code goes here>>
这样,对代码的更改不会影响您的变量,如果您必须手动编写代码而不是依靠像样的汇编器,这将非常方便。