.SAV. Первый блок - некоторое количество ячеек со служебной информацией (типа - точка входа, начальное значение стека, размер загрузки) плюс свободные ячейки и место под стек (если по умолчанию, то начальное значение стека 1000(8)). Если специально не задавать значение стека и не играться абсолютными секциями, код и данные пойду с адреса 1000, и в .SAV файле это будет второй блок. То есть, если не принимать специальных мер, минимальный размер программы в RT - 2 блока. При тех же условиях в RSX - 4 блока (первые два - служебная информация).
889(10) байта - два блока - итого размер .SAV три блока или 512*3=1536 байт. Фраза выше говорит о полном не знании даже RT
Аха. И применение на атомных станциях PDP говорит о полном Г среди современных контроллеров.
И я про тоже - полное не знание фактов.
В RSX нет понятия системных процессов. Есть ядро, есть драйвера, есть задачи (task), которые часто по простому называют программами. Некоторые задачи выполняет специальные функции (например, F11ACP - работа с файловой системой, все запросы к файлам идут через неё, но с точки зрения RSX - это задача)
Текст "супер-программы" приведён вышеКод:.TITLE TEST
.MCALL RDBBK$, WDBBK$
.MCALL CRRG$S, CRAW$S
.MCALL SPND$S
.MCALL EXTK$S
.MCALL EXIT$S
.LIST ME
START:
CRRG$S #RDB
MOV RDB+R.GID, WDB+W.NRID
CRAW$S #WDB
SPND$S
EXIT$S
RDB: RDBBK$ 100000, , , <RS.ATT!RS.DEL!RS.EXT!RS.WRT!RS.RED>
WDB: WDBBK$ 1, 200, 0, 0, 200, <WS.64B!WS.MAP!WS.DEL!WS.EXT!WS.WRT!WS.RED>
.END START
[* КОНЕЦ ТЕКСТА *]
Потому что, в отличии от вас, я знаю - особенности системы команд PDP-11 и как работает Macro-11 и почему он не может "просчитать" простые переходы
А в нормальных конторах работала многопользовательская RSX с памятью от мегабайта (например СМ-1420 или СМ-1600) и нормальной поддержкой программ, которым требуется немного больше памяти, чем 64 кб. Компиляторы с Fortran-а, кстати, генерировали код, который умел это дело.
А в RSX и XM мониторе подход очень похожий, так что написать программу особого труда не составит. Кстати, опять же - компилятор с Fortran-а позволял писать программы, которым требовалось больше 64 кб, причём в наличии было два варианта библиотек поддержки - для программы, которая будет работать под XM монитором (по сути аналогичный подход, как и в RSX) или (внезапно) под SJ или FB, при условии, что проц PDP с MMU и размером памяти больше 56 кб
В целом, вывод не изменился - знания PDP-11 у человека на уровне начинающего чайника. Можно больше не обращать внимания на его перлы про PDP-11 и ОС для PDP-11
- - - Добавлено - - -
А это пример программы (на MACRO-11) (загружает virgin (когда загрузчик RSX ещё не прописан в нулевой сектор раздела) RSX из под RT на CF )
Пример того, как может выглядеть программа на языке ассемблера. Используется СТАНДАРТНЫЙ Macro-11Код:R$$T11 = 1
M$$EXT = 1
.NLIST
.INCLUDE /KXX:DSMAC.MAC/
.INCLUDE /KXX:MYMAC.MAC/
.INCLUDE /KXX:ASCII.MAC/
.INCLUDE /KXX:HWDF.MAC/
.LIST
MODULE NAME=<BOOTZF>, VER=<01>, COMM=<BOOT RSX from ZF>, TYPE=<NOSECT>
.MCALL .ASSUME
;
; This module contains a special driver used by BOOT and SAVE
; to read and write system images.
;
; Driver inputs:
; R2 = Not used
; R3 = Not used
; R4 = Unit number
; R5 = 0 Use CSR address stored in the driver
; R5 <> 0 use CSR address stored in R5
;
; Driver outputs:
; R0 = Residual block count
; R2 = Possible memory size from configuration table
; R1 = Device name in ascii
; R4 = Physical unit number
; R5 = CSR address
;
; INITIALIZE PROPER BIT SETTING FOR SSR3
;
S3$BTS==0 ; INIT TO NO BITS SET
.IF DF M$$EXT
S3$BTS==S3$BTS!MM3.UN!MM3.22 ; ENABLE 22 BIT MODE AND UNIBUS MAP
.ENDC
PROCEDURE BOOTZF
BEGIN
;
; from SAVe - code analog
;
NOP ; 00
GOTO 10$ ; 02
HLBN: .WORD 0 ; 04 high lbn
LLBN: .WORD 26084.+2 ; 06 low lbn 26084 + 2
; magic number
.BYTE 020 ; 10 PDP-11 instruction set
.BYTE 133 ; 11 All controllers except pcxxx
.BYTE 041 ; 12 ODS-1 file format
.BYTE 163 ; 13 1's compliment checksum
10$:
GOTO 20$
20$:
LET @#PS :B= #PR7
;
; For virgin system image
;
LET BBLKH := @#4 ;;; (HIGH) LBN of image
LET BBLKL := @#6 ;;; (LOW) LBN of image
LET BLEN := ZFLLEN ;;; length of load file
LET R5 := (PC)+ ; Csr address - set in savcm or minjbb
$BBCSR: .WORD 1
; Default to what boot rom passed
; (0= use CSR in special driver)
; (+ = use value passed in r1)
; (- = use value stored in $BBCSR)
IF RESULT IS GT THEN ; LE - in IO page
LET $BBCSR := R1 ; CSR from hardware boot
END
IF #MM0.EN OFF.IN @#SSR0 THEN
LET R5 := #KISAR0 ;;; INIT POINTER TO MAPPING REGISTERS
LET R1 := #0 ;;; INIT I SPACE MEMORY OFFSET
REPEAT
LET KISDR0-KISAR0(R5) := #77406 ;;; SET I SPACE 4K RW
LET (R5)+ := R1 ;;; SET I SPACE APR OFFSET
LET R1 := R1 + #200 ;;; ADVANCE I SPACE OFFSET
UNTIL R5 HI #KISAR7 ;;; DONE YET? IF HI YES
LET @#KISAR7 := #177600 ;;; SET UP I/O PAGE MAPPING
.IF DF M$$EXT
LET @#SSR3 := #S3$BTS ;;; SET UP SSR3
.ENDC
LET @#SSR0 := @#SSR0 + #1 ;;; MM0.EN == 1 ; ENABLE MAPPING
END
; 00000000-03777777
; 04000000-07777777
; 10000000-13777777
; 14000000-17777777
; 14000000-14777777
; 15000000-15777777
; 16000000-16777777
; 16776000 -> 167760
; 2000
; 17000000-17777777
LET @#KISAR6 := #167760 ;;; SET 140000 MAPPING
LET R4 := #140000
LET R1 := #0
THRU R3 := #256.*2
LET (R4)+ := (R1)+
END
LET R2 := #0
LET R4 := R0 ; R0 from hardware boot - unit number
IF RESULT IS PL THEN ; If MI, this is the second incarnation
LET SP := #3000 ; Set up stack for special driver
LET PUSH := #0 ; put on a stopper
LET PUSH := #0 ; two parts
END
LET R5 := $BBCSR ; CSR from hardware boot
LET SP := #$ZFDRV-BOOTZF+140000
JMP @#$ZFDRV-BOOTZF+140000
.BLKW 20. ; Stack
$GOTO $ZFDRV
END BOOTZF
;
; Special driver
;
PROCEDURE $ZFDRV
; Note - At this point the following must be true:
; R0 = unit number from hardware bootstrap, possibly with flag bit
; R2 = 0 tell the driver not to use UMRs
; R3 = 0 no BAE offset needed
; R4 = unit number from hardware bootstrap, possibly with flag bit
; R5 = 0 or the CSR address (see $BBCSR above)
BEGIN
GOTO ZF0 ;;; Br around fixed stuff
SZFNAM: .WORD "ZF ;;; Device name
SZFCSR: .WORD ZFBASE+P$CSR2 ;;; Default CSR address
SZFFUN: .BYTE CS.RD, -1 ;;; Function code and unit number
ZF0:
IF R5 EQ #0 THEN
LET R5 := SZFCSR ;;; CSR address supplied? If no, get saved CSR address
END
LET SZFCSR := R5 ;;; save CSR
LET SZFFUN+1 :B= R4 ;;; save unit number
LET R5 := SZFCSR ;;; get saved CSR address
LET (PC)+ := @#KISAR3
SKxSAR: .WORD 0
LET R1 := (PC)+ ;;; Get buffer address
ZFSA: .WORD 0
LET CARRY := CLEARED ;;; Convert to 32wd block address
LET R1 := R1 L.ROTATE 2
SWAB R1
LET ZFSA := R1
LET R3 := PC + #<SZFFUN-.> ;;; Set address for pic code
LET (PC)+ := @#4 ;;; Save starting block number
ZFBLKH: .WORD 0 ;;; Current LBN (HIGH)
LET R1 :B= 1(R3) OFF.BY #^C<377>
MUL #40, R1 ;;; offset for 1Gb
LET ZFBLKH := ZFBLKH + R1 ;;; OFFSET
LET (PC)+ := @#6 ;;; ...
ZFBLKL: .WORD 0 ;;; Current LBN (LOW)
IFB #CS.RD NE (R3) THEN ;;; Is this a write function?
LET MOVE := (PC)+ ;;; Set generic fill silo instruction
LET (R2) := (R1)+ ;;; Fill silo instruction
END
;
; Common parameter setup
;
REPEAT
LET @#KISAR3 := ZFSA ;;; Setup APR3 to map to buffer
LET R4 := (PC)+ ;;; Get load length
ZFLLEN: .WORD 498.-2 ;;; ?? was 3
LET (R5) := #DC.STA!DC.NIE
NOP
NOP
LET R5 := R5 + #P$STAT-P$CSR2
;
; controller basic loop
;
ZFLOOP:
.ASSUME CS.BSY EQ <^O200>
REPEAT UNTILB (R5) PL #0 AND #CS.DRD SET.IN (R5)
LET R0 :B= ZFBLKH+1 ;;; HIGH BYTE HIGH LBN - "TRACK"
LET R0 := R0 OFF.BY #^C<17> SET.BY #DH.PRM ;;; ONLY LOW 4 BITS PLUS FIXED BITS
LET P$DH-P$CMD(R5) :B= R0 ;;; "TRACK"+fixed bits
LET P$CYLH-P$CMD(R5) :B= ZFBLKH ;;; "HYGH CYLINDER" BYTE
LET P$CYLL-P$CMD(R5) :B= ZFBLKL+1 ;;; "LOW CYLINDER" BYTE
LET P$SNUM-P$CMD(R5) :B= ZFBLKL ;;; "SECTOR"
LET R1 := #255. ;;; MAX CHUNK
IF R1 HI R4 THEN ;;; MAX CHUNK LESS OR EQUAL REST LENGTH ?
LET R1 := R4 ;;; NO - REST OF IMAGE
END
LET (PC)+ := R1
ZFCHNK: .WORD 0
LET P$SCNT-P$CMD(R5) :B= R1 ;;; SECTOR COUNT
LET (R5) :B= (R3) ;;; Start the function
.REPT 5.
NOP
.ENDR
;
; Common transfer loop
;
COMMON:
;
; Perform silo/memory transfers - empty silo OR, fill silo before writing
;
LET R2 := R5 + #P$DBUF-P$CMD ;;; Copy CSR address, point to IDE data buffer
LET (PC)+ := ZFCHNK
ZFCNK2: .WORD 0
REPEAT
REPEAT
.ASSUME CS.BSY EQ <^O200>
REPEAT UNTILB #CS.RD EQ (R3) ORB (R5) PL #0
UNTIL #CS.DRQ SET.IN (R5)
IF #CS.ERR SET.IN (R5) GOTO ERR ;;; If error, try again
LET R1 := #60000 ;;; Set base for APR3 mapping
THRU R0 := #256. ;;; Set count of words in silo
MOVE:
LET (R1)+ := (R2) ;;; Empty silo (will change to fill silo)
END ;;; Loop until done
LET @#KISAR3 := @#KISAR3 + #10 ;;; Update APR3 mapping by 256. words
TST (PC)+ ;;; Is the NXM trap setup?
TRPFLG: .WORD 0 ;;; Flag=0 first time thru
IF RESULT IS EQ THEN
LET (PC)+ := @#4 ;;; Save current trap 4 vector
TRPPC: .WORD 0 ;;;
LET (PC)+ := @#6 ;;; ...
TRPPS: .WORD 0 ;;;
LET TRPFLG := TRPFLG + #1 ;;; Indicate that we have been here
LET @#6 := #PR7 ;;; Set new PS
LET R0 := PC + #<TRP4-.> ;;; Calculate trap address
LET @#4 := R0 ;;; Set new PC
END
LET ZFCNK2 := ZFCNK2 - #1
UNTIL RESULT IS EQ
TST (PC)+ ;;;
ERR:
SEC
UNTIL RESULT IS CC
LET ZFSA := @#KISAR3
LET R1 := ZFCHNK ;;; RESTORE CHUNK SIZE
LET ZFBLKL := ZFBLKL + R1 ;;; Update current LBN
LET ZFBLKH := ZFBLKH + CARRY
LET R4 := R4 - R1 ;;; ONE CHUNK LESS
LET ZFLLEN := R4 ;;; SAVE REST
IF RESULT IS HI GOTO ZFLOOP
GOTO ZFDONE
END $ZFDRV
;
; We are finished
;
PROCEDURE TRP4
BEGIN
$GOTO ZFDONE
END TRP4
PROCEDURE ZFDONE
BEGIN
LET @#4 := TRPPC ;;; Restore PC
LET @#6 := TRPPS ;;; Restore PS
LET R5 := R5 + #P$CSR2-P$STAT
;
; For virgin system
;
LET R0 := R5
LET R1 := (PC)+
BBLKH: .WORD 0 ;;; (HIGH) LBN of image
LET R2 := (PC)+
BBLKL: .WORD 0 ;;; (LOW) LBN of image
LET R3 :B= 1(R3) OFF.BY #^C<377> ;;; Get unit number
LET R4 := SZFNAM ;;; Get device name
LET R5 := (PC)+ ;;; Get device name
BLEN: .WORD 0 ;;; length of load file
;
; For SAVe
;
; LET R0 := R4 ;;; Get residual block count
; LET R1 := SZFNAM ;;; Get device name
; LET R4 :B= 1(R3) ;;; Get unit number
; LET R5 := R5 + #P$CSR2-P$STAT
LET @#KISAR3 := SKxSAR
;
; For virgin system
;
LET PC := #4672
LET PC := #65772
ZFEND:
;
; For SAVe
;
RETURN ;;; must be return and must be last
;;; instruction in ZF special driver
;;; (SAV assumed this is return
;;; and replace it in VBN 1,2,3 of
;;; SAVED IMAGE !!!!!
END ZFDONE
;
; Driver table
;
DRVS:
.ASCII /ZF/ ; ZF driver
.WORD ZFLLEN ; Address of load length
.WORD ZFSA ; Address of buffer address
.WORD SZFFUN ; Address of function code/unit
.WORD $ZFDRV ; Driver entry address
.WORD <ZFEND-$ZFDRV>/2 ; Size of driver in words
.WORD CS.WT ; Write function code
.WORD CS.RD ; Read function code
.WORD 0 ; Unit select bits
.WORD SZFFUN ; Address of function code word
.WORD SZFCSR ; Address of CSR address
PROCEDURE START
BEGIN
RESET
LET SP := #10000
LET R0 := #0
LET R1 := #BOOTZF
THRU R2 := #<ZFEND+2-BOOTZF>/2
LET (R0)+ := (R1)+
END
LET R0 := #1
LET R1 := #ZFBASE+P$CSR2
LET PC := #0
END START
END BOOTZF
.END START
- - - Добавлено - - -
Забыл ещё про разделяемые библиотеки - аналог .dll - но с точки зрения системы - это области памяти с загруженными кодом и/или данными. Ещё один вариант (но уже достаточно экзотичный) использования разделяемой библиотеки - для доступа к (части) страницы в/в со стороны непривилегированных задач.

