6

Although useless, it’s widely known the first Intel and derivative CPUs like the Z80 didn’t set a limit on the instruction size. This means that it was possible to fill the whole RAM/ROM with a single instruction through repeating a prefix, and it would still execute!

For example, you could happen an infinity of 0x2E bytes before a mov sp,bp and still get the instruction executed.

If generally the limit today is 15 bytes, I remember the 286 had a 10 bytes limit... But generally what’s the last x86 CPU from that instruction set that didn’t cap instruction size ?

15
  • 2
    I'd suggest being more explicit about what is meant by "a single instruction". If I recall, on the 8086, something like "SS: Rep Movsb" would behave semantically as though the SS prefix was a separate instruction; though would prevent an interrupt from being serviced before executing the next instruction, it would not prevent an interrupt from being serviced during a repeated instruction, nor would it get re-executed when the interrupt returned.
    – supercat
    Jun 2, 2020 at 21:42
  • 1
    @user2284570: I think the 8088/8086 were intended to support segment prefixes with repeated string instructions, though they're not safe to use when interrupts are enabled. I suspect the size limits were imposed to avoid the possibility that a user-mode program that attempted to execute a sequence of 65,000 prefix bytes could block interrupts for an excessively long time.
    – supercat
    Jun 2, 2020 at 21:50
  • 3
    @supercat The 8086 rep story is a little more complicated: The 8086 does support interrupted prefixed instructions just fine - but only if there is just a single prefix. If there are multiple prefixes, like in SS: REP MOVSW, only the last one is handled when restarting after an interrupt. This means that SS: REP MOVSW transfers the right amount of data (REP is never forgotten), but from a wrong source, whereas REP SS: MOVSW performs just a single SS: MOVSW after an interrupt. The 80C86 fixed this issue. Jun 2, 2020 at 21:53
  • 1
    @user2284570 The change to RISC under the hood happened with the Pentium Pro, which is more than ten years after the 80286 that alreday had the 10-byte limit. Jun 2, 2020 at 21:55
  • 2
    It's not a "bizarre quirk". Several opcode bytes of the x86 instruction space are reserved to be "prefix bytes". These bytes can be put before an instruction to modify the execution of the instruction (like auto-repeating memory transfer instructions, chosing differnt segment registers or holding the bus lock pin during execution). There is no rule on the 8086 (or any later processor) that redundant prefix bytes are forbidden, and even most modern processors will execute instructions with redundent prefix bytes, as long as the total size limit is not exceeded... Jun 2, 2020 at 22:09

2 Answers 2

13

In Appendix C (on software compatibility to the 8086), the Intel 286 users manual states the following about instruction length (Page C-2):

Do not Duplicate Prefixes.

The 80286 sets an instruction length limit of 10 bytes. The only way to violate this limit is by duplicating a prefix two or more times before an instruction. Exception 6 occurs if the instruction length limit is violated. The 8086/8088 has no instruction length limit.

This seems to be wrong, though. The correct exception is exception 13 (0Dh). It is correctly documented in the manual on Page B-9:

#GP 13 General Protection (Selector or Zero Error Code)

This exception is generated for all protection violations not covered by the other exceptions in this section. Examples of this include:

  1. An attempt to address a memory location by using an offset that exceeds the limit for the segment involved.

  2. An attempt to jump to a data segment.

  3. An attempt to load SS with a selector for a read-only segment.

  4. An attempt to write to a read-only segment.

  5. Exceeding the maximum instruction length of 10 bytes.

The limit has been raised by the 80386 to 15 bytes, because operands and addresses may be 32 bit instead of 16 bit, and you also have extra prefixes. You can find it in the 80386 programmers manual, page 168:

9.8.13 Interrupt 13 ── General Protection Exception

All protection violations that do not cause another exception cause ageneral protection exception. This includes (but is not limited to):

  1. Exceeding segment limit when using CS, DS, ES, FS, or GS

[...]

  1. Exceeding the instruction length limit of 15 bytes (this can occur only if redundant prefixes are placed before an instruction)

The limit of 15 bytes is valid until today.

So if we just consider x86 processors, the last processor that did not implement a logic to detect oversized instructions is the 8086 or the 80186. I can not find any reference to a 10-byte limit in the iAPX 86/88/186/188 reference manual, so I am confident to claim that the last Intel x86 CPU that allowed instructions of unlimited size is the 80186/80188. The instruction size limit became part of the architecture with the 286 and was changed with the transition from 16 bits to 32 bits.

As all AMD processors up to the (original, non-enhanced) Am486 are licensed copies of the Intel Design, the same applies to AMD processors. For the 16-bit processors, there are other third-party manufacturers like Siemens and Harris, they are also licensed copies of the respective Intel models, so no behavioural difference is to be expected.

There are 80186-compatible processor cores in microcontrollers produced until 2000s at least. They most likely do not include the instruction size limit. The same applies to the V30 and microcontrollers based on it. Basically everything that doesn't have the protected mode (and doesn't have the general protection fault) also doesn't have the instruction size limit.

10
  • And what about clones ? Did ᴀᴍᴅ manufacture 16 bits x86 ? Jun 2, 2020 at 23:33
  • So it mights mean other manufacturers built ᴄᴘᴜ without a limited decoder after the 80186 ? What about the Nec V30Mx which is still manufactured today ? Jun 2, 2020 at 23:37
  • @MichaelKarcher AMD (and others) licenced up and including the 486.
    – Raffzahn
    Jun 2, 2020 at 23:42
  • @MichaelKarcher the Nec V30Mx supports most 286 and later specific instructions. For protected mode I’d agree to upload something to my Casio. Jun 3, 2020 at 1:31
  • @user2284570 "the Nec V30Mx supports most 286 and later specific instructions." - as does the 80186. I checked the V30MX manual and see no hints that the V30MX has an instruction size limit, especially as the V30 manual defines the prefixes as individual instructions. Jun 3, 2020 at 7:09
-6

Although useless, it’s widely known the first Intel and derivate CPUs like the Z80 didn’t set a limit on the instruction size.

Mind to explain what limit you're asking about? There is no instruction on an 8080 with more than three bytes - and no Z80 instruction with more than 5 (*1).

Furthermore, adding multiple/repeated prefixes don't create a longer instruction - just as adding NOPs in front won't do so.

If generally the limit today is 15 bytes, I remember the 286 had a 10 bytes limit…

Should this maybe refer to some (prefetch) buffer limits?

Such buffers only organize the way memory access is interleaved with instruction execution. Instructions can (and often do) cover multiple buffers - that's why the 486 had two 16 byte buffers. Access to various parts of the instruction was done by different parts of the pipeline at different times.

Others, like the 68000 or most RISCs didn't have any buffers but read the instruction stream synchronously with its execution.

Caches have blurred that even more.

But what generally the last CPU from that instruction set which didn’t cap instruction size ?

It seems as if you assume the reverse of the cause and effect. CPU hardware is made to comply to a certain instruction set (for this CPU), thus serving all sizes that are needed, not limiting them.

Further, asking for a 'last' seems to imply a singular line of development, does it? CPUs are defined all the time. There is no singular before and after. Not even within a single company and linage like Intel and their x86 implementations. Strategies for instruction fetch, buffering, decoding and execution have not only changed many times - this includes 'reverting' to something done previously.


*1 - In fact, from a CPU's perspective there is no Z80 instruction with more than 3 bytes, as each prefix is handled as a separate instruction, which is clearly shown by pulling the M1 signal with prefix and opcode byte.

18
  • 1
    @Wilson Serious, undocumented opcodes, i.e. bugs, as argument about instruction length?
    – Raffzahn
    Jun 2, 2020 at 21:11
  • 2
    @Raffzahn "Further, adding multiple/repeated prefixes don't create a longer instruction - the same way as adding NOPs in front won't do." - Intel disagrees with you in this regard: The 80286 processor's users says about instruction length: "Do not Duplicate Prefixes: The 80286 sets an instruction length limit of 10 bytes. The only way to violate this limit is by duplicating a prefix two or more times before an instruction. Exception 6 occurs if the instruction length limit is violated." (See document 210498-005, page C-2) Jun 2, 2020 at 22:37
  • 2
    @Raffzahn Do you have any source for the claim that the 10-byte limit on the 80286 is related to a buffer in that processor (e.g. a block diagram or architectural description that referes to this buffer)? Jun 2, 2020 at 22:57
  • 1
    @lvd As said, there are different views here. 1) As shown, being interruptable or not isn't a definite criteria. 2) first, isn't it rather DD CB? At least that's how Zilog says. Second, while the 4th byte can be seen as opcode, it can as well be read as data (bit and reg), and last, this is no difference from an LD A,x ADD A,y LD y,A sequence, which as well only works that way. 3) Latching a word ahead isn't the same as a buffer and doesn't change the synchronous nature. 4) True, it's a state machine - like any sequential CPU. Exactly like above LD/ADD sequence is as well. No difference.
    – Raffzahn
    Jun 4, 2020 at 8:57
  • 1
    Well, bug (or rather avoidance of actual bugs with interrupts after taken branches) in 6502 is a definite argument that interruptability is not an argument. That's a nice. I could also ask what is meant to be 'asynchronous' or 'synchronous' nature when talking about prefetches. Almost every CPU, at least that with a single clock, is synchronous by definition.
    – lvd
    Jun 4, 2020 at 13:42

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .