Как известно, для каждого динамического объекта (записи или массива) в куче выделяется блок, имеющий структуру Kernel.Block (не экспортирована). При этом реально указатель указывает на ADR(block)+4, т.е. тег оказывается по смещению -4 от адреса указателя.

При модификации управления может понадобиться ввести в структуру блока дополнительное поле/поля. Таким образом, получается, что смещение указателя относительно начала блока уже не +4, а +N байт.
Однако это смещение захардкордено во многих местах ядра, без введения какой-либо константы. (Увы, это касается и констант, характерных для 32битности, и кое-чего ещё....).

Публикую требуемые исправления (переход к единой константе). Предлагаю внести их в ядра сборок, чтобы заинтересованные в изменениях управления памятью люди уже не мучались.

Также в паре мест при увеличении размера блока используется "магический литерал" + 19 (а затем DIV 16 * 16).
Я не понял с ходу, что это (ниже будет видно в коде).
Эту константу я тоже вынес, как const19, и увеличиваю её на разницу между новой длиной заголовка блока и 4.

Итак, для стандартного Block blockDataOffs = 4. Если вы вводите в Block в начале (до tag) какие-то поля, то увеличиваете эту константу на их размер.

## Код:
```
CONST      
  blockDataOffs = 4;
  const19 = 19 + blockDataOffs - 4;
```


## Код:
```
PROCEDURE Mark (this: Block);
....
   IF (flag >= 2) & (actual < this.last) & (offset < -blockDataOffs) THEN   (* next array element *)
....
                  S.GET(actual + offset, son);
                  IF son # NIL THEN
                     DEC(S.VAL(INTEGER, son), blockDataOffs);
...
```


## Код:
```
PROCEDURE MarkGlobals;
...
               IF p # 0 THEN Mark(S.VAL(Block, p - blockDataOffs)) END
```


Далее, процедура Next. При модифицированном блоке либо модернизировать вариант в машкодах (позиция поля tag-то уже не та), либо перейти на высокоуровневую процедуру (раскомментировать её и закомментировать маш. код).
Тут же встречается магическая константа 19:

## Код:
```
PROCEDURE Next (b: Block): Block;   (* next block in same cluster *)
      VAR size: INTEGER;
   BEGIN
      S.GET(S.VAL(INTEGER, b.tag) DIV 4 * 4, size);
      IF ODD(S.VAL(INTEGER, b.tag) DIV 2) THEN INC(size, b.last - S.ADR(b.last)) END;
      RETURN S.VAL(Block, S.VAL(INTEGER, b) + (size + const19) DIV 16 * 16)
   END Next;
```


## Код:
```
PROCEDURE Insert (blk: FreeBlock; size: INTEGER);   (* insert block in free list *)
      VAR i: INTEGER;
   BEGIN
      blk.size := size - blockDataOffs; blk.tag := S.VAL(Type, S.ADR(blk.size));
..
```


## Код:
```
PROCEDURE OldBlock (size: INTEGER): FreeBlock;   (* 
...
      s := size - blockDataOffs;
```


## Код:
```
PROCEDURE LastBlock (limit: INTEGER): FreeBlock;   (* size MOD 16 = 0 *)
.....
      s := limit - blockDataOffs;
```


В NewBlock снова встречается магическое 19:
## Код:
```
PROCEDURE NewBlock (size: INTEGER): Block;
      VAR tsize, a, s: INTEGER; b: FreeBlock; new, c: Cluster; r: Reducer;
   BEGIN
      ASSERT(size >= 0, 20);
      IF size > MAX(INTEGER) - const19 THEN RETURN NIL END; (* Этого не было до release 1.6 *)
      tsize := (size + const19) DIV 16 * 16;
....
      IF b = NIL THEN
         IF dllMem THEN
....
                  b.size := (new.size - 12) DIV 16 * 16 - blockDataOffs
.....
         ELSE
....
                        b.size := (root.size - a + b.size + 4) DIV 16 * 16 - blockDataOffs
                     ELSE
                        b := S.VAL(FreeBlock, S.VAL(INTEGER, root) + a);
                        b.size := (root.size - a) DIV 16 * 16 - blockDataOffs
                     END
         END;
      END;
      (* b # NIL *)
      a := b.size + blockDataOffs - tsize;
```


## Код:
```
PROCEDURE Init;
....
         free[i].size := (root.size - 12) DIV 16 * 16 - blockDataOffs;
```
