Вопрос Kick Assembler, манипулирование переменной в цикле

Я пытаюсь изучить логику мнемоники и попробовал этот простой тест на C64 asm, сделанный с помощью VSCode и Kick Asm. По сути, я пытаюсь напечатать символы последовательности в верхнем левом углу от 0 до 9, а затем наоборот. Это рабочая попытка:

.label SCREEN_RAM = $0400   // Start of C64 screen memory
// --- Variable ---
counter: .byte 0    
//backCounter: .byte 39       
animationDirection: .byte 1  // Start animation going forward (0=backward, 1=forward) 
.var backCounter = $39  

BasicUpstart2(main) 

main:
    lda #0              // Initialize a counter to 0
    sta counter 
    jmp checkloop

checkloop:
    ldy animationDirection  // Load the current direction flag
    cpy #1
    beq print_loop_forward 
    //.break
    //lda #10     // Load the desired value into the accumulator
    //sta counter      // Store the value from the accumulator into 'counter'
    ldy #backCounter //#$39 
    jsr print_loop_backwards
    jmp exit2

print_loop_backwards: 
    //.break
    //ldy #backCounter //#$39 no!
    ldx counter            // Load the counter into Y register (for offsetting)
    tya
    sta SCREEN_RAM, x     // Store the character on the screen with offset 
    dey 
    inc counter
    ldx counter
    cpx #20
    bne print_loop_backwards         // Compare with 10 (decimal) 
    rts

print_loop_backwards_not_working: 
    .break
    lda #backCounter //#$39 
    ldx counter            // Load the counter into Y register (for offsetting)
    sta SCREEN_RAM, x     // Store the character on the screen with offset

    dec backCounter
    //.break
    inc counter
    ldx counter
    cpx #20
    bne print_loop_backwards         // Compare with 10 (decimal) 
    rts
    
 
print_loop_forward:  
    //.break
    lda counter            // Load the counter value into the accumulator
    //cmp #0
    //beq exit
    clc
    adC#$30              // Add $30 to convert to ASCII 
    ldx counter            // Load the counter into Y register (for offsetting)
    sta SCREEN_RAM, x     // Store the character on the screen with offset
    
    inc counter
    ldx counter
    cpx #10
    bne print_loop_forward         // Compare with 10 (decimal)
    //.break
    lda #0
    sta animationDirection
    jmp checkloop 

exit:               // Label for the exit point
    rts

exit2:               // Label for the exit point
    lda #$21            // Load the counter into Y register (for offsetting)
    ldx #$99
    sta $0500, x
    rts

Как вы можете видеть, я попробовал другой способ сделать это в этом цикле:

print_loop_backwards_not_working

Сначала я попробовал эту попытку, безуспешно изменив переменную «backCounter» во время цикла, но не понял, почему переменная не отражает такие изменения, как «счетчик», который я могу изменить с помощью INC. Пробовал с помощью DEC, как вы видите, но также и с SEC\SBC#$1.

Очевидно, хотя безуспешно пробовал этот метод, строка:

ldy #backCounter //#$39 

был закомментирован.

Надеюсь, кто-нибудь поможет мне прояснить это!

lda #backCounter помещает адрес backCounter в аккумулятор (ну, младший байт адреса, поскольку это все, что помещается). Это постоянное значение, на которое не повлияет увеличение или уменьшение backCounter.
jasonharper 18.08.2024 04:29
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
1
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Коды операций 6502/6510 имеют немедленный, абсолютный и косвенный режимы. Если вы хотите использовать адрес памяти в качестве счетчика, вам следует использовать абсолютный режим, который можно представить, как показано ниже.

LDA $FFFF

или это версия Zeropage;

LDA $FF

Вы пытаетесь использовать немедленный режим, который выглядит следующим образом:

LDA #$FF

Итак, у вас есть три разумных варианта.

1 – Используйте абсолютный режим, как показано ниже;

LDY backCounter
...
DEC backCounter

Абсолютный режим считывает backCounter из адреса памяти в регистр Y, и когда нам нужно уменьшить счетчик, мы непосредственно уменьшаем память. Когда мы прочитаем адрес памяти в следующий раз, он уже уменьшится.

2 – Используйте модифицирующий код. Я не рекомендую это, я делюсь этим как альтернативный вариант.

label1:
    LDY #backCounter
    ...
    DEC label1+1

Здесь мы используем немедленный режим и уменьшаем параметр кода операции в памяти. Не забывайте, что если вы не сбросите параметр, ваш код в следующий раз не будет работать с начальным значением backCounter.

3. Используйте регистры напрямую. Это самый быстрый метод, который вы уже используете в своем рабочем примере.

LDY #backCounter
...
DEY

Пока у вас есть бесплатные регистры, вам следует использовать регистры. Если у вас закончились регистры, используйте абсолютный режим, например «LDY backCounter», — ваш второй лучший вариант. Самомодифицирующийся код время от времени может быть очень полезен. Но это не самый безопасный вариант и может вызвать некоторые побочные эффекты. В современных процессорах самомодифицирующийся код может быть ограничен или, по крайней мере, вызывать проблемы с кэшированием и значительно замедлять работу вашего кода. Но в старую добрую эпоху 8-битных процессоров самомодифицирующийся код можно было безопасно использовать, если вы знали, что делаете.

Другие вопросы по теме