Chuck Guzis via cctalk wrote on Date: Mon, 10 Apr 2017 15:21:08 -0700 > Thanks for the list--I was aware of the various Java engines and the WD > P-code engine, but had never run into the SCAMP.
I just found an academic Pascal microprocessor from 1980 called EM-1 and described all the way to the chip layout level: http://authors.library.caltech.edu/27046/1/TR_2883.pdf > Okay, I've got to ask--exactly what made the 8086 unsuitable for C, but > work with Pascal? I'll admit to puzzlement about this statement. I talked about the problem with far pointers and C in the post about the iAPX 432. The 64KB segments in the 8086 were not a problem for Pascal (or Smalltalk, as shown by the Xerox PARC Notetaker computer) because each heap object and each proceedure can live in a different segment to take advantage of the whole memory. A single object (like an array) can't be split into multiple segments which limits us to small objects (this is not a problem for Smalltalk which can completely hide such splits as shown in the Mushroom computer). One big difference between Pascal and C is that while C seems to have nested lexical scoped like Algol at first glance (and indeed it is often list as being part of the "Algol family") it really doesn't. An object either lives in the heap or is in the local stack frame. You can declare new variables inside { ... } and they will shadow variables with the same name declared outside of these brackets but this has no effect on the runtime structures. Pascal, on the other hand, allows proceedures to be declared inside other proceedures and these nested scopes can access stuff declared in the more external scopes. This requires some runtime structures that can be awkward to implement in many processor architectures. An expression like: x := y; might generate quite a bit of code if "x" was declared one level up and "y" was declared three levels up. But on the 8086 we could have pointers to the frames of the various lexical levels saved at the start of the current frame just like the "display registers" in the Burroughs B5000. We could have something like: mov di,[bp-2*3] ; lexical level 3 mov ax,[di-20] ; y mov di,[bp-2*1] ; lexical level 1 mov [di-8],ax ; x Filling up those pointers on each proceedure entry can take some time so a popular alternative for when nested references were not too common was to have a linked list of runtime frames and code like: mov di,[bp-2] ; lexical level 1 mov di,[di-2] ; lexical level 2 mov di,[di-2] ; lexical level 3 mov ax,[di-20] ; y mov di,[bp-2] ; lexical level 1 mov [di-8],ax ; x Being able to directly address constant offsets from the base pointer and offsets from the result of that greatly reduces the number of instructions needed to support lexical scoping in Pascal. For C, constant offsets from a pointer are great for getting at the elements of structs, so this is a nice thing to have in any case and most RISCs implement this. -- Jecel p.s.: I haven't programmed in x86 assembly since 1987 so don't trust the above code fragments