Скопировать байт из стека без изменения указателя стека (Motorolla 68000)?
Мне задают следующий вопрос:
Three bytes are pushed onto the runtime stack. Copy the third
byte from the runtime stack to D0 without changing the stack pointer
Итак, у меня есть стек, который выглядит так:
| |
| |
|cc | <-- SP points to cc
|bb |
|aa |
Я не уверен, как бы я скопировал значение cc в регистр D0. Я знаю, что могу выкинуть это из стека вот так... MOVE.B (SP)+,D0
, но это изменит указатель стека на bb
Кроме того, в чем разница между пользовательским стеком и стеком времени выполнения? Например, если меня попросят извлечь байт из стека пользователя (A6), но затем вставить его в стек времени выполнения, как я это сделаю? Есть идеи?
2 ответа
Вам нужно использовать смещение указателя стека. Также помните, что стеки идут назад (как правило,:)) так
move.b (sp), d0
даст в вашем примере $cc
move.b 2(sp), d0
вы получите $ аа в d0
надеюсь, это поможет
Это вопрос с подвохом, и он не отвечает, не зная, каким образом байты попали в стек, особенно из-за странности при использовании регистра адреса с режимом предопределения -(An), когда An=A7=SP. Если, например, байты были выдвинуты так:
move.b #$aa,-(sp)
move.b #$bb,-(sp)
move.b #$cc,-(sp)
|$??| +5
|$aa| +4
|$??| +3
|$bb| +2
|$??| +1
|$cc| <--- SP points here
Указатель стека уменьшается на два за каждый ход. 68k трактует это иначе, чем другие регистры адресов, потому что адрес указателя нечетного стека вызовет исключение адреса (по крайней мере, для MC68000) при следующей попытке вставить слово или длинное слово (явным или неявным путем вызова подпрограммы) из-за слово / длинный доступ по нечетному адресу. Это задокументировано в справочном руководстве семьи, стр. 2-7: http://www.freescale.com/files/archives/doc/ref_manual/M68000PRM.pdf
Однако если бы 3 байта были частью более крупного объекта, например длинного слова, они были бы размещены по последовательным адресам:
move.l #$ccbbaa??,-(sp)
|$??| +3
|$aa| +2
|$bb| +1
|$cc| <--- SP points here
Таким образом, ответ - что-то вроде "move.b 4(sp),d0", если они были выдвинуты как байты, но "move.b 2(sp),d0", если они были частью большего объекта.