Передать адрес памяти регистром
Как передать адрес памяти из регистра в другой? Моя следующая подпрограмма получает адрес строки памяти из стека (да, это необходимо), а затем пытается вставить в D1
регистрируется, но это не работает, и эмулятор EASy68k вылетает (или заходит в бесконечный цикл?), когда я пытаюсь запустить это.
Код:
START ORG $1000
MOVE.L T,D0
MOVE.L D0,-(SP)
BSR PRINTS
PRINTS:
MOVE.L D0,(SP)+
MOVE.W D0,A1
MOVE #14,D0
TRAP #15
RTS
T DC.B 'HELLO',0
END START
ОБНОВЛЕНИЕ: я обновил способ, поскольку аргументы выдвигаются и извлекаются из стека. Изменено для использования PEA
инструкция, которая выглядит так, делает именно то, что я хочу, но все равно не работает.
START ORG $1000
PEA T(PC)
*MOVE.L D0,-(SP)
BSR PRINTS
ADDQ.L #4,SP
MOVE #9,D0
TRAP #15
PRINTS:
MOVE 4(SP),A1
MOVE #14,D0
TRAP #15
RTS
1 ответ
Чтобы получить аргумент в стек правильно, вам нужно сделать:
LEA T, A0
MOVE.L A0, D0
MOVE.L D0, -(SP)
или же
PEA.L T
Чтобы правильно получить аргумент из стека, вам не нужно вставлять его в вызываемую функцию. Это потому что BSR
выдвигает обратный адрес. Вместо этого вам нужно использовать индексированную адресацию следующим образом:
MOVE.L (4,SP), A1 ; read argument from stack, overlooking return address
И затем, чтобы завершить его, вам нужно "вытолкнуть" аргумент из стека в вызывающем (а не вызываемом), добавив его после BSR
инструкция:
ADDA.L #4, SP ; remove argument from stack.
Результирующая программа (которую я тестировал в EASy68K) выглядит следующим образом:
ORG $1000
START:
PEA.L T ; push argument to stack
BSR PRINTS ; call PRINTS; also pushes return address on stack
ADDA.L #4, SP ; remove argument from stack.
SIMHALT
PRINTS:
MOVE.L (4,SP), A1 ; read argument from stack, overlooking return address
MOVE.L #14, D0
TRAP #15
RTS
T DC.B 'HELLO', 0
END START ; last line of source
И не забывайте, что SIMHALT
впереди PRINTS
, Вы не хотите попадать из вашего основного кода в свои подпрограммы.
О, и как вы, вероятно, обнаружили:
PEA.L T(PC)
работает вместо
PEA.L T
Основным отличием является размер кода. Первый использует относительную к ПК адресацию для генерации адреса, а второй сохраняет полный 32-битный адрес в объектном коде.