program t67_strparam; { t67 -- a STRING VALUE parameter. CALC.INC:17 is procedure Center(S : AnyString); TP3 puts a value parameter's whole SIZE on the stack (TPSRC7 tstscal), so a string[20] parameter is 21 bytes: the caller copies into the callee's slot, with the length byte at the lowest address (BP+4). That is what makes it a VALUE: the callee has its own copy, and mutating S must not touch the caller's variable. The fixture proves both halves: - `Show (t)' then `writeln (t)' prints `hello' again, so S[1] := 'X' changed only the copy; - `Show ('world')' shows a LITERAL argument being copied too. A by-address implementation would print `Xello' after the first call. The bytes come from a DS-relative byte loop, not REP MOVSB: MOVS addresses through ES, and nothing here establishes ES = DS. } var t : string[20]; procedure Show (S : string[20]); begin writeln (S); S[1] := 'X' end; begin t := 'hello'; Show (t); writeln (t); Show ('world'); writeln (t) end.