Почему значение, переданное в 0(SP), доступно только в 4(SP)?

Почему значение передается в 0(SP) доступно только при 4(SP)? например, мне нужно передать номер printn от 0(SP) вместо 4(SP) (как это используется в рутине) или это не будет работать. Что мне не хватает?

MOVE #12,D0
MOVE D0,0(SP)   here I use 0 offset

PRINTN:
        MOVE 4(SP),D1   |and here 4. Shoudln't be the same?
        MOVE #3,D0
        TRAP #15
        RTS

2 ответа

Решение

В соответствии с вашим кодом, я предполагаю, что PRINTN - это подпрограмма (функция, процедура и т. Д.), И она вызывается с использованием JSR. Если это так, вы должны возражать против функционирования JSR: это

  • уменьшает SP на 4
  • помещает адрес возврата (начало инструкции, следующей за JSR) в память по адресу в SP
  • помещает адрес подпрограммы (из инструкции JSR) в ПК

поэтому после этого все смещения за пределами SP, которые вы знали, должны быть увеличены на 4. И, да, значение в 0(SP) доступно как 4(SP) из подпрограммы, 28(SP) должно быть заменено таким же образом с 32(SP) и так далее. RTS делает наоборот - увеличивает SP на 4.

Более того, каждый PUSH и POP меняют его; если вы сохраняете 2 регистра в стеке, после этих PUSH все смещения дополнительно увеличиваются на 8, пока не будут выполнены соответствующие POP. Это легко отслеживается компиляторами, но сложнее - людьми; это, например, будет дополнительным аргументом, почему x86 изобрел BP в дополнение к SP.

Если мы предположим, что PRINTN это подпрограмма, в которую вы попали JSR / BSR тогда на ваш вопрос ответит описание операции для JSR:

SP – 4 → Sp; PC → (SP); Destination Address → PC

То есть адрес возврата теперь находится на вершине стека, и все, что было на вершине стека до JSR теперь будет в 4(SP), и так далее.

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