Pascal was first implemented for the Cyber-a CDC mainframe of the 1960s and 1970s, which, like many modern processors, had excellent consistent command execution performance, but also a significant decrease in performance for branches. This and other characteristics of cyber architecture have probably greatly influenced the design of Pascal for loops.
The short answer is that assigning a loop variable will require additional security code and confused optimizations for loop variables that can usually be processed in 18-bit index registers. In those days, software performance was highly rated due to hardware costs and the inability to speed it up in any other way.
Long answer
The Control Data Corporation 6600 family, which includes Cyber, is a RISC architecture using 60-bit central memory words referenced by 18-bit addresses. Some models had a (expensive, therefore unusual) option, Compare-Move Unit (CMU), for direct access to 6-bit character fields, but otherwise there was no support for "bytes" of any type. Since CMU could not be calculated in general, most of the Cyber code was created for its absence. Ten characters in one word was the usual data format until support for lowercase characters was replaced by a preliminary 12-bit character representation.
The instructions are 15 bits or 30 bits in length, except that CMU instructions are 60 bits long. Thus, up to 4 instructions packed into each word, or two 30 bits, or a pair of 15 bits and one 30 bits. 30-bit instructions cannot span words. Since branch assignments can only refer to words, transition goals are word aligned.
There is no stack in architecture. In fact, the RJ procedure call statement is intrinsically inherently. RJ changes the first word of the called procedure, writing down the transition to the next command after where the RJ instruction is. The called procedures return to the caller, jumping to their beginning, which is reserved for feedback. Procedures begin with the second word. Most compilers used a helper function to implement recursion.
The register file has eight instances of each of the three types of registers, A0..A7 for address processing, B0..B7 for indexing, and X0..X7 for general arithmetic. Registers A and B - 18 bits; X registers - 60 bits. Setting A1-A5 has the side effect of loading the corresponding register X1-X5 with the contents of the loaded address. Setting A6 or A7 writes the corresponding contents of X6 or X7 to the address loaded into register A. A0 and X0 are not connected. Registers B can be used in almost every instruction as a value to add or subtract from any other register A, B or X. Therefore, they are great for small counters.
For effective code, register B is used for loop variables, since they can use direct comparison instructions (B2 <100, etc.); Comparison with X-registers is limited to zero, so comparing an X-register by 100, say, requires subtracting 100 and testing the result less than zero, etc. If you allowed the assignment of a loop variable, the 60-bit value must be checked by the range before assigning to register B. This is a real hassle. Mr. Wirth probably believed that the hassle and inefficiency were not worth the utility - a programmer can always use a while or repeat ... until in this situation.
Extra weirdness
Several unique features of the one-on-Pascal language relate directly to aspects of Cyber:
pack keyword: either one “character” consumes a 60-bit word, or ten characters per word are packed.- (unusual)
alfa type: packed array [1..10] of char - internal procedures
pack() and unpack() for handling packed characters. They do not perform conversion on modern architectures, but only type conversion. - weird
text files vs file of char - no newline character. Record management was explicitly called using
writeln - While
set of char was very useful for CDC, it was not supported on many subsequent 8-bit machines due to excessive memory usage (32-byte variables / constants for 8-bit ASCII). On the contrary, a single Cyber-word could control the native set of 62 characters, omitting a new line and something else. - full evaluation of the expression (compared to labels). They were implemented not by jumping and setting one or zero (as most code generators do), but using CPU instructions that implement logical arithmetic.