Передать адрес памяти регистром

Как передать адрес памяти из регистра в другой? Моя следующая подпрограмма получает адрес строки памяти из стека (да, это необходимо), а затем пытается вставить в 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-битный адрес в объектном коде.

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