В MIPS 20-летней и более давности, например. Борьба со сбросом конвеера при переходе.
В MIPS 20-летней и более давности, например. Борьба со сбросом конвеера при переходе.
Последний раз редактировалось form; 03.12.2016 в 22:24.
PDP-11/83, Электроника МС0511 (УК-НЦ), DECserver 90M
Q-Bus: H9278-A, DLV11-J, DZQ11, DHV11, DELQA-M, LPV11, CQD-420/TM, DRV11
PMI: KDJ11-BF, MSV11-JE
VT220, CM7209
Для понятности можно написать по=другому
(ERRor eXIT - выход по ошибке, временная метка тут как-то не очень, если не делать .ENABLE LSB, то она почти наверняка окажется недоступной, ибо стандартная область действия временных меток - между двумя постоянными.)Код:TST #261 ERRXIT = .-2 RTS PC
- - - Добавлено - - -
А вот прием для обслуживания кучи одинаковых устройств. Пример - несколько терминалов, подключенных через обычные ВП1-065, допустим, на плате КТЛК-6. Программу обслуживания их прерываний (код), обычно, пользуют одну и ту же, а переменные данные (кольцевые буферы и текущие адреса в них, всякие счетчики, флажки и пр.) располагают в таблице, для каждого терминала - своей. В этом случае программа обслуживания конкретного прерывания от терминала должна поместить в какой-то заданный регистр адрес этой таблицы, перед этим сохранив его, и уйти на общую программу обслуживания прерывания от терминалов. Так вот, можно воспользоваться следующим приемом, допустим, адрес таблицы нужен в R0 (подсмотрено в ядре ДИАМСа.):
Вектора же заполняем указателями на команду JSR R0,@(PC)+, то есть на смещение -4 от начала таблицы, каждому терминалу - своей. Таким образом, прерывание от терминала этой командой сохранит R0 в стеке, поместит в этот R0 адрес начала таблицы и уйдет на общую программу обслуживания терминалов.Код:INTn: JSR R0,@(PC)+ ; смещение -4 от начала таблицы. Команда. .WORD TRMINT ; Смещение -2 от начала таблицы. Адрес общей программы обслуживания ; прерываний от терминала. nTABLE: ; Собственно таблица, ее начало .........
Обычно эти таблицы генерятся динамически в занятом для них куске свободной памяти при запуске программы. При этом сначала берут адрес этого участка памяти для таблицы, записывают его в вектор конкретного терминала, потом в память по этому адресу пересылают с автоинкрементом сначала код 4037 (тот самый JSR), затем адрес программы обслуживания терминалов, получившийся после этих двух пересылок адрес сохраняем в качестве адреса начала таблицы для этого терминала, после чего генерим собственно таблицу в ее начальном состоянии.
Итого, накладные расходы на занесение в R0 адреса таблицы конкретного терминала и переход к общей программе обслуживания всего два слова (4 байта) на каждый терминал.
Последний раз редактировалось AFZ; 05.12.2016 в 10:48.
Кто мешает тебе выдумать порох непромокаемый? (К.Прутков, мысль № 133)
Ну что, вроде ожили? Чего было-то? Форум в воскресенье висел или лежал?
Пардон, месье, я вижу — Вы в нашем деле новичок и ещё не успели познать всю радость извращений!А что Вы скажете на пару_строк кода 8080?:
Как Вы думаете, куда будет передано управление по метке error и какой такой метод адресации использован в команде по метке noerror?Код:error EQU noerror+1 noerror: CPI 37h RET
Правда, у 80-го процессора есть однобайтные команды условного возврата из подпрограмм, так что ему будет дешевле написать условный возврат, нежели вышеприведённый код. А с вызовом подпрограмм уже не так: у 11-го процессора вызов занимает 4 байта, а у 8080 — три, что, казалось бы, даёт ему экономию кода в 25%. Но!!! Вы верно заметили про "такие методы адресации"! В 11-м процессоре есть такие методы адресации, которые требуют при вызове подпрограммы всего 2-х байтов кода, так что при их использовании 8080 уже отстаёт по краткости кода, причём на 33%. Однако и это не всё!
Практическая польза при программировании в среде RT-11 на ассемблере заключается в возможности вызовов подпрограмм вообще без команд вызова подпрограмм, а просто по именам! Вот пример такого кода, который типа печатает на экране результат А*В+D/F:
Где-то поодаль находятся коды подпрограмм F_MUL, F_DIV, F_ADD (она же F_SUB) и F_TYPE, а также переменные.Код:F_MUL А, В, С ; вызов подпрограммы умножения А и В с занесением результата в С F_DIV D, E, F ; вызов подпрограммы деления D на E с занесением результата в F F_ADD C, F, G ; вызов подпрограммы сложения C и F с занесением результата в G F_TYPE G ; вызов подпрограммы печати G на экране
Программистская фишка здесь заключается в настройке регистра (например, R4) на начало такого блока "данных" и завершении каждой из подпрограмм командой не RET, a JMP @(R4)+, так что указанный регистр выполняет функцию как бы счётчика команд, если считать F_MUL (и прочие) командами, а не именами подпрограмм. Но поскольку и эти "команды", и данные к ним находятся вперемежку, то этот же регистр выполняет функцию и как бы указателя стека, только растущего не вниз, а вверх, как и счётчик команд. Как Вам, месье, понравится такое извращение?
На самом деле я всего лишь привёл упрощённый пример куска фортрановского кода от RT11, который, впрочем, без упрощений не стеснялся применять и в своих ассемблерных программах. Понятно, что в вычислительных задачах количество вызовов наиболее ходовых подпрограмм (+, -, * и /, а также присвоения и преобразования данных) столь велико, что экономия по одному слову памяти на каждый вызов, а, главное, экономия времени от неиспользования обычного стека (как это было бы при обычных вызовах CALL) получается весьма заметной.
Всего доброго.
Евгений.
Последний раз редактировалось form; 05.12.2016 в 15:43.
PDP-11/83, Электроника МС0511 (УК-НЦ), DECserver 90M
Q-Bus: H9278-A, DLV11-J, DZQ11, DHV11, DELQA-M, LPV11, CQD-420/TM, DRV11
PMI: KDJ11-BF, MSV11-JE
VT220, CM7209
С любовью к вам, Yandex.Direct
Размещение рекламы на форуме способствует его дальнейшему развитию
Сложные вопросы можно даже в RT-11 организоватьА мой любимый "сложный" вопрос - про фортран: CALL SUB(1) - объяснить что делает данный операторКод:.TY TEST.MAC .TITLE TEST .MCALL .EXIT,.PRINT .PSECT CODE,I TEXT: .ASCIZ /I=D/ ;XXX EVEN START: .PRINT #TEXT ;PRINT .EXIT ;EXIT .PSECT DATA,D .ASCIZ /I<>D/ .END START .MAC TEST .LIN TEST/RUN I=D .LIN TEST/RUN/ID I<>D .
Большинство знакомых программеров (даже тех кто знает фортран с далеких времен) отвечает неправильно (хотя с появлением всякого дерьма вроде g77 их ответ можно принять)![]()
PDP-11/83, Электроника МС0511 (УК-НЦ), DECserver 90M
Q-Bus: H9278-A, DLV11-J, DZQ11, DHV11, DELQA-M, LPV11, CQD-420/TM, DRV11
PMI: KDJ11-BF, MSV11-JE
VT220, CM7209
Холмс и Ватсон летят на воздушном шаре, поднялись уже высоко - за облака. Ватсон не выдержал и спрашивает:
- Холмс, как Вы думаете, где мы находимся?
- В корзине воздушного шара, дорогой Ватсон, - невозмутимо ответил Холмс.
Вот у Вас как код написан неряшливо, так же неряшливо Вы и вопрос пытаетесь задать. Обратите внимание: он у Вас даже не заканчивается вопросительным знаком! А ведь известно: какой вопрос, такой и ответ. По-моему, такая неаккуратность нехороша для программиста, выглядит как неуважение к остальным...
Всего доброго.
Евгений.
Я попытку ответа сделаю основываясь на опыте ПАСКАЛЬ + МАКРО11 и сторонние obj библиотеки,
такая команда вызывает глобальную процедуру (функцию) SUB и передаёт ей входящий параметр = 1.
- - - Добавлено - - -
в чём вы видите неряшливость кода? вы листинги Корчагина видели ? )))
Что правильно если внимательно прочитать как он написан
- - - Добавлено - - -
Здесь и заключается ошибка
То есть конечно 1 в качестве параметра передается, но есть нюанс - у фортрана аргументы векторные. С точки зрения паскаля можно считать, что они всегда var, а это уже совсем другая песня
- - - Добавлено - - -
Разумеется не неряшливый код "был, но дискеты потерялись, а потому примеров не дам"?![]()
PDP-11/83, Электроника МС0511 (УК-НЦ), DECserver 90M
Q-Bus: H9278-A, DLV11-J, DZQ11, DHV11, DELQA-M, LPV11, CQD-420/TM, DRV11
PMI: KDJ11-BF, MSV11-JE
VT220, CM7209
Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)