assembly - 为什么我的斐波那契 6502 在 144 和 233 时出现故障?
问题描述
以下程序:
PORTB = $6000
PORTA = $6001
DDRB = $6002
DDRA = $6003
E = %10000000
RW = %01000000
RS = %00100000
VARX = $4000
VARY = $4001
VARZ = $4002
NUM = $4005
DIV = $4006
RES = $4007
MOD = $4008
BACK_TO_FRONT = $4020
.org $8000
reset:
lda #%11111111 ; Set all pins on port A to output
sta DDRA
lda #%11100000 ; Set top 3 pins on port B to output
sta DDRB
lda #%00011100 ; Set 8-bit mode; 2-line display; 5x8 font
sta PORTA
lda #0 ; Clear RS/RW/E bits
sta PORTB
lda #E ; Set E bit to send instruction
sta PORTB
lda #0 ; Clear RS/RW/E bits
sta PORTB
lda #%01110000 ; Display on; cursor on; blink off
sta PORTA
lda #0 ; Clear RS/RW/E bits
sta PORTB
lda #E ; Set E bit to send instruction
sta PORTB
lda #0 ; Clear RS/RW/E bits
sta PORTB
lda #%01100000 ; Increment and shift cursor; don't shift display
sta PORTA
lda #0 ; Clear RS/RW/E bits
sta PORTB
lda #E ; Set E bit to send instruction
sta PORTB
lda #0 ; Clear RS/RW/E bits
sta PORTB
lda #$0
sta VARX
lda #$1
sta VARY
lda #$a
sta DIV
loop:
lda VARX
clv
clc
adc VARY
clc
clv
sta VARZ
lda VARY
sta VARX
lda VARZ
sta VARY
lda VARY
sta NUM
ldx #$0
store_digits:
jmp divide
return_from_div:
lda MOD
sta BACK_TO_FRONT, x
inx
lda RES
sta NUM
lda #$0
cmp NUM
bcc store_digits
dex
print_digits:
ldy BACK_TO_FRONT, x
lda digit_table, y
sta PORTA
lda #RS ; Set RS; Clear RW/E bits
sta PORTB
lda #(RS | E) ; Set E bit to send instruction
sta PORTB
lda #RS ; Clear E bits
sta PORTB
dex
sec
cpx #$1
bcc print_digits
ldx #$0
delay:
lda #%00000100
sta PORTA
lda #RS ; Set RS; Clear RW/E bits
sta PORTB
lda #(RS | E) ; Set E bit to send instruction
sta PORTB
lda #RS ; Clear E bits
sta PORTB
cpx #$f
beq next
inx
jmp delay
next:
lda #%10000000
sta PORTA
lda #0 ; Clear RS/RW/E bits
sta PORTB
lda #E ; Set E bit to send instruction
sta PORTB
lda #0 ; Clear RS/RW/E bits
sta PORTB
jmp loop
divide:
lda #$0
sta RES
lda #$0
sta MOD
div_loop:
lda NUM
cmp DIV
bcc answer
lda NUM
sec
sbc DIV
clc
clv
sta NUM
inc RES
jmp div_loop
answer:
lda NUM
sta MOD
jmp return_from_div
digit_table:
.word $8c0c
.word $cc4c
.word $ac2c
.word $ec6c
.word $9c1c
.org $fffc
.word reset
.word $0000
在 65C02(WDC 版本)上运行。连接到 ROM(从地址 0x8000 开始)和 RAM 芯片(地址 0x4000)和连接到 HD44780(1602 标准 LCD)的 VIA (65C22)。
该程序有效,但部分有效。它输出 1 然后 2 然后 3 ... 然后 89 而不是 144 打印 1,而不是 233 打印 2. 然后 1 再然后 98 ??? 然后是61。
解决方案
您决定返回的方式print_digits
不正确:
; I've omitted the SEC since it's pointless
cpx #$1
bcc print_digits
print_digits
仅当无符号小于 1时才会跳转X
。唯一可能的值是 0,因此上述也可以描述为跳转到print_digits
ifX
等于 0。
如果我们查看整个print_digits
循环,则可以使用以下伪代码对其进行描述:
x = numDigits - 1;
do
{
print(digits[x]);
x--;
} while (x == 0);
唯一能给你正确输出的场景numDigits
是 1 或 2。对于任何大于此的值,你将打印一个数字,然后退出循环。
你真正想要的是这样的:
x = numDigits - 1;
do
{
print(digits[x]);
x--;
} while (x >= 0);
也就是说,替换:
dex
sec
cpx #$1
bcc print_digits
和:
dex ; Updates the N flag after decrementing X
bpl print_digits ; Jump if N is clear, i.e. if X >= 0
推荐阅读
- c# - 如何修复错误“由于以下错误而无法加载 PowerShell 管理单元 Microsoft.PowerShell.Diagnostics:无法加载文件或程序集”
- javascript - 对文本元素进行条件操作?
- docker - 不需要的升级 ElasticSearch 版本
- javascript - 为什么我的 Ajax 请求不能使用 post 方法?
- python - 追加 csv 的列值
- android - Android webView - 无法加载某些链接 - 收到无效流的 RST
- fp-ts - 使用 FP-TS 消耗 IO
- serial-port - RS-232 波特率和线长对接收的串行位的影响
- android - OkHttp connectTimeout 细节
- python - Keras耗时太长,不知道我用的是GPU还是CPU