6502 Ассемблер - Команда RTS и стек

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

"В стеке есть следующие значения (сначала верхний элемент): 0x01, 0x02, 0x03, 0x04, 0x05, 0x06 По адресу 0xc000 находится инструкция jsr 0xABCD. Какое значение будет сохранено в счетчике программ после цикла выборки / выполнения и что будет верхним элементом стека. ? "

Я знаю, что счетчик программы будет 0xABCD, но меня смущают элементы стека. Я знаю, что в архитектуре 6502 стек растет сверху вниз (с 0x01FF до 0x0100). Итак, я полагаю, указатель стека указывает на элемент 0x01, верно?

Теперь адрес возврата должен быть program counter + 3, потому что есть команда next, поэтому я бы сказал, что 0xc003 будет помещено в стек, но в порядке обратного порядка байтов, поэтому c0 будет верхним элементом. Это верно?


person user66875    schedule 30.01.2014    source источник
comment
Я бы назвал начальную точку стека (0x1ff) нижней, а 0x100 верхней. В машине LE модель согласованности будет заключаться в том, чтобы хранить «03» в меньшем адресе.   -  person Aki Suihkonen    schedule 30.01.2014
comment
Просто предупреждение: в 6502 JSR отправляет (адрес возврата - 1) в стек. То есть RTS увеличивает его после вытягивания.   -  person cyco130    schedule 04.04.2014
comment
@ cyco130 есть ли какое-нибудь объяснение такой конструкции? Мне кажется довольно странным хранить адрес-1 вместо фактического адреса следующей инструкции, с которой будет продолжено выполнение.   -  person BarbaraKwarc    schedule 16.07.2018
comment
@BarbaraKwarc У меня нет окончательного ответа, я могу только догадываться: я знаю, что 6502 всегда извлекает два байта в первых двух циклах каждой инструкции. Для 1-байтовых кодов операций он отбрасывает лишний и не увеличивает ПК (который уже был увеличен для извлечения выброшенного второго байта). Для 2-байтовых кодов операций он использует как байты, так и увеличивает PC. А для 3-байтовых он увеличивает PC, выбирает последний байт, использует его и еще раз увеличивает PC. В JSR (3-байтовый код операции) он должен помещать счетчик программы в стек перед последним увеличением PC.   -  person cyco130    schedule 17.07.2018
comment
Да, я предполагал, что приращение ПК - это последняя стадия каждого машинного цикла, жестко запрограммированная, поэтому он должен это делать в любом случае (после извлечения его из стека), и, чтобы компенсировать это, он сдвигает адрес на 1 меньше ( что не так уж и сложно, если он подталкивает его до увеличения ПК на последнем этапе). Но было бы неплохо, если бы это было подтверждено какой-нибудь официальной документацией. И тот факт, что условные переходы используют адрес следующей инструкции для вычисления смещений, как бы сбивает меня с толку такими предположениями: q   -  person BarbaraKwarc    schedule 20.07.2018


Ответы (2)


Начните с регистра S, равного $F9, что означает, что все после этого на странице $0100 является стеком. Содержимое памяти следующее:

$01FA: 01 02 03 04 05 06

$ABCD: A6 23       LDX $23
; rest of the body of the subroutine
$AC03: 60          RTS

$C000: 20 CD AB    JSR $ABCD
$C003: BD 40 06    LDA $0640,X

Инструкция JSR помещает адрес последнего байта инструкции. В этом случае адрес последнего байта - $C002. Сначала вставляется старший байт, так что младший байт находится в младшем адресе: нажмите $C0, затем нажмите $02, затем перейдите к $ABCD. После этого стек будет выглядеть следующим образом: $C002 в порядке байтов с прямым порядком байтов вверху, а S стал $F7.

$01F8: 02 C0 01 02 03 04 05 06

Подпрограмма с $ABCD завершится инструкцией RTS, которая здесь показана $AC03. Эта инструкция извлекает младший и старший байты счетчика программы. А затем, поскольку адрес возврата указывает на последний байт предыдущей инструкции, он добавляет 1. $C002 плюс единица - это $C003, адрес первого байта следующей инструкции в вызывающей программе.

person Damian Yerrick    schedule 10.11.2014

Я считаю, что то, что происходит на jsr,

stack[stack_pointer] = return_high
stack_pointer--
stack[stack_pointer] = return_low
stack_pointer--
pc = jsr address

поэтому, если вы утверждаете, что указатель стека указывает на 0x01, а 0x02 - это более низкий / меньший адрес, тогда 0x01 и 0x02 будут перезаписаны, и когда вы нажмете свою подпрограмму, стек будет указывать на 0x03.

person old_timer    schedule 30.01.2014
comment
ответ будет яснее с таблицей ... адрес - ›значение - person Core; 31.01.2014