Функциональные указатели в сборке 68к для Ti-89
Я уже несколько месяцев пытаюсь построить кросс-компилятор B для моего Ti-89 и наконец-то настал момент, когда я хотел бы создать сборку, которую выполняет мой калькулятор. Язык "B" в том смысле, что существует только 1 тип, который является целым числом / указателем. Я не понимаю, как реализовать указатели функций на этой платформе. Я рассматривал реализацию указателей на функции следующими способами:
- Сохранение адреса первой инструкции с использованием непосредственного значения
- Получение адреса первой инструкции с использованием счетчика программы и смещения
- Сохранение только смещения и вычисление адреса первой инструкции при выполнении перехода.
Первый способ определенно не будет работать, так как программы сборки на Ti-89 перед выполнением копируются в оперативную память. У меня не было бы способа узнать во время компиляции, где будет расположена функция. Кроме того, согласно Руководству для разработчиков Ti-89/Ti-92 Plus на стр. 24, "программы ASM могут перемещаться во время кучи мусора. Указатели на переопределяющий системный код станут недействительными". Это будет означать, что второй метод также не обязательно будет работать, так как возможно, что сбор мусора в куче происходит после вычисления адреса первой инструкции. Предполагая, что то, что говорится о перемещении программы, является правильным, это может привести к перемещению всей функции. Третий метод будет работать в определенных случаях, но проблема в том, что я не обязательно знаю, где в программе сборки будет вызываться функция. Таким образом, для каждого места, где может быть вызвана функция, мне понадобится разное смещение, и, насколько я знаю, у меня нет способа рассчитать это смещение.
TIGCC допускает указатели на функции, так как, черт возьми, они их реализуют? Я что-то упускаю?
Ссылки:
- Руководство для разработчиков Ti-89 / Ti-92: https://tiplanet.org/modules/archives/downloads2/1446144333/sdk8992pguide.pdf
- TIGCC: http://tigcc.ticalc.org/doc/
- Мой проект: https://github.com/been-jamming/TiBc
2 ответа
Если вы хотите получить адрес функции в том же модуле компиляции, вам следует использовать относительную адресацию ПК. Ты можешь использовать lea
(загрузить эффективный адрес) для сохранения адреса в любом регистре адресов (a0
-a6
, Технически, a7
тоже работает, но не делай этого. a6
также часто резервируется как указатель кадра):
lea myfunc(PC),a2
Это можно вызвать с помощью jsr (a2)
(перейти к подпрограмме) или, в некоторых случаях, просто используя jmp (a2)
(по сути, прыжок в хвост, если параметры в стеке уже соответствуют параметрам функции, ожидаемым myfunc
).
Кроме того, вы можете использовать pea
(нажмите эффективный адрес), чтобы поместить адрес в стек:
pea myfunc(PC)
Это может быть либо параметр функции, либо, если он остается на вершине стека, вы перейдете по этому адресу с помощью следующего rts
, Например, если у вас есть функция, которая заканчивается так:
lea myfunc(PC),a2
; some other code (not changing a2, not messing with the stack)
bsr foo ; local subroutine
jsr (a2)
rts
Вы также можете написать:
pea myfunc(PC)
; some other code (not messing with the stack)
bra foo ; tail call to local subroutine foo
; on return this will jump to myfunc
; when myfunc ends, it returns to the caller of this function
Я последовал предложению @lurker. Сборка, кажется, просто помещает адрес в стек без особой информации. Из тестирования, если моя функция была названа my_func
тогда сборка выглядит так move.l #my_func,-4(%fp)
который просто нажимает указатель на функцию. Я предполагаю, что ассемблер преобразует его в непосредственное отношение к ПК, а не только к действительному адресу в двоичном файле. Это будет означать, что я неправильно прочитал документацию, на которую ссылался ранее. Я думаю, что он пытался сказать, что вы не можете ссылаться на адреса в двоичном файле в памяти, но вы можете ссылаться на адреса во временной копии, которую она помещает в ОЗУ. Это имело бы больше смысла, так как операционная система не будет работать в фоновом режиме, пока программа сборки все равно работает. Я должен предположить, что сборка мусора это то, что может произойти только после выполнения программы.