При передаче аргументов в коде программы - они всегда вычисляются на этапе компиляции (иначе овчинка не стоит выделки). Ведь всё затевается лишь для того, чтобы сэкономить одно слово при каждом вызове подпрограммы.
Вид для печати
На этапе компиляции вычислить реальный адрес однако ну никак не получится если заранее неизвестен способ загрузки. Попробуй SAV файлу (у которого именно на этапе компиляции все вычисленно) загрузить скажем с адреса 1002 (бервый блок и выше) и посмотреть много ли программ заработают :)
Для PRUN специально REL формат выбран чтобы можно было любой файл с позиционнозависимым кодом грузить и не париться.
Или ты имеешь в виду порочность самого интерфейса когда надо адрес писать после вызова EMT/подпрограммы? :)
Если автор программы хочет передавать в коде реальные адреса - его программа не может быть перемещаемой. Если же автор хочет передавать, например, смещения от начала программной секции сообщений - проблем с перемещаемостью не возникнет.
Но по сути дела - нет принципиальной разницы между вызовом с передачей аргумента в коде или в регистре. И в том, и в другом случае правила одни и те же.
Речь немного о другом - когда в программе используется передача аргументов в коде - это практически всегда означает их вычисление на этапе компиляции/компоновки. Иначе такой способ не имеет преимуществ.
Ась?
То есть то, что такие проги есть и работают - пофигу. Их все-равно нет потому что не может быть? ;)
MOV #LABEL,Rx ;ПРОБЛЕМА
А писать программы когда нужно в аргументах передавать LABEL-START оправдано далеко не всегда. В частности для загрузки всяких драйверов в ПП совершенно неоправданно ибо лекго без всякой позиционнонезависимости все делается :)[/QUOTE]
Когда ты сам пишешь то, что вызываешь, ты можешь делать что хочешь. А если речь идет о EMT, надо полагать, что вызывается не твой обработчик EMT и передаешь ты ему то, что он просит, а не то, что тебе удобнее. И тут на этапе компиляции ничего вычислить не удастся если только это не частный случай - загрузка REL к примеру.
Да, но при этом или программа грузитя/мапится всегда в одно место или реализован механизм перемещения (REL) либо ты сам пишешь так, чтобы оно не зависило от местоположения и в этом случае ты так или иначе довычисляешь адреса на ходу если нужно именно адрес знать (например строки).
Для упрощения - приведите пример .PRINT когда все вычислено на этапе компиляции и работает при любом положении :)
Если кого-то ( например - нас ) интересует, чем передача аргументов в коде отличается от передачи аргументов в регистре или в стеке, то единственное отличие - в размере кода.
Когда аргументы могут быть вычислены на этапе компиляции/компоновки - их передача в коде позволяет экономить по одному слову на каждый случай передачи аргумента (для подпрограммы с 5-ю аргументами такого типа - при каждом вызове будет экономиться по 5 слов).
Если же аргументы должны вычисляться на этапе выполнения - их передача в коде не будет иметь никаких преимуществ и чаще всего будет занимать больше места, чем передача тех же аргументов в регистре или стеке.
Ну так понятно, что вычислять адрес на этапе выполнения нужно только тогда когда это оправдано - в драйвере устройства например. Хотя начиная с 5.2 и без этого можно обойтись :)
А способ передачи - это уже от фантазии зависит.
В RSX к примеру есть два варианта вызова одних и тех же директив - либо все аргументы в стеке либо адрес этих самых аргументов в стеке - пользуй по обстоятельствам :)
А с програмерской точки зрения есть еще третий вариант - второй случай, но список аргументов пишешь как в первом (кладется в psect) :)
Я тут упоминал про РАФОС и RSXизм тех кто его делал - так вот там для всех макрокоманд с AREA также сделано - можно заготавливать блоки AREA, можно пихать их в PSECT :)
Но сделано довольно криво - не у всех аргументов отбрасываются '#', что приводит к помещению в текст программы описаний, несовместимых со стандартом MACRO-11, при том, что точно такие же вызовы обычного формата проходят без проблем.
Например:
Можно заметить, что в первом вызове, при формировании блока аргументов - у последнего параметра ( счётчик слов #0 ) решётка была-таки отброшена.Код:000000 AREA: .Read BLOCK, #0, #BUF, #256., #0
A 000000 .BYTE #0,8.
000002 .WORD 0
A 000004 .WORD #BUF
A 000006 .WORD #256.
A 000010 .WORD #1
000012 .Read #AREA, #0, #BUF, #256., #0
000012 MOV #AREA,%0
000016 MOV #0+<8.*^O400>,(0)
000022 CLR 2.(0)
000026 MOV #BUF,4.(0)
000034 MOV #256.,6.(0)
000042 MOV #1,8.(0)
000050 EMT ^O375
Да просто делать пытались расширяя существующий набор макросов да запутались :)
В RSX-то три формы вызовов отличаются написанием: XXX$, XXX$C и XXX$S, а тут попытались все в один флакон запихать.
Полезность же этого - вопрос спорный - просто RSXовец делал - так сказать для души. Статусы выхода тоже по-RSXовски звучат в описании: ERROR, SEVERE, FATAL вместо привычных (в RT-11) ERROR, FATAL, UNCONDITIONAL. И описание статусов соответственно хромает ибо SEVERE самим своим названием подразумевает, что произошло несколько ошибок :)
Кстати, а в фодосе тоже такое делали или там не стали? :)
---------- Post added at 20:51 ---------- Previous post was at 20:46 ----------
Кстати посмотрел на "кривость". Так это как раз правильно.
Директивы генерации DPB (пардон, AREA) должны использовать формы пригодные для .WORD и это документировано.
---------- Post added at 20:53 ---------- Previous post was at 20:51 ----------
Вот собственно выдержка из руководства:
Код:LABEL: .PRGREQ BLOCK,ARG1,...,ARGN
ГДЕ
АRG1,...,АRGN
- ДОПУСТИМЫЕ АРГУМЕНТЫ ДЛЯ ДИРЕКТИВ .WОRD И .ВYТЕ.