-1

ADD( const, memory) is the messiest of all, this code sequence looks something like the following:

  • Fetch the instruction byte from memory.
  • Update EIP to point at the next byte.
  • Decode the instruction.
    • If required, fetch a displacement for use in the effective address calculation
    • If required, update EIP to point beyond the displacement value.
  • Fetch the constant value from memory and send it to the ALU.
  • Update EIP to point beyond the constant’s value (at the next instruction in memory).
  • Get the value of the source operand from memory and send it to the ALU.
  • Instruct the ALU to add the values.
  • Store the result back into the memory operand.
  • Update the flags register with the result of the addition operation.

This is from The Art of Assembly Language book. Why is the EIP been updated 2 even 3 times?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
newbee
  • 36
  • 7
  • 1
    If you have variable length instructions, like the x86 has, you have to decode it first to be able to decide the length. – Bo Persson May 25 '16 at 14:13

1 Answers1

3

You can never observe EIP pointing into the middle of an instruction being decoded. That's just the author's notation. Real hardware obviously doesn't decode in a slow iterative process, since it's hardware not software.

x86 is complicated to decode, and operand-size prefixes even change the length of the rest of the instruction in the case of opcodes that take a 16 or 32bit immediate depending on operand-size. Intel CPUs actually stall on this when decoding. (It's called an LCP stall).

However, that notation sounds weird, since the variable-length opcode implies the length of the instruction + immediate. Decoding the prefixes + opcode tells you the total length of the instruction, except for the addressing mode, which might has a SIB byte and/or a displacement.

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • Is there any time though that IP gets updated multiple times in one IC? Can we not say that's a mistake? – Evan Carroll May 15 '18 at 00:41
  • 2
    @EvanCarroll: 8086 did decode instructions one prefix per cycle. So it did have some kind of counter. Whether it was called IP or not is a question of semantics, not CPU design. (Although I'd guess that any CPU with a physical IP or EIP register wouldn't use it as a scratch register during instruction decode, because it needs the original instruction address in case there's an exception during decode or execution. OTOH, instructions that reference (E)IP during execution (like the value pushed by `call`, or `jmp rel8`) use the address of the *next* instruction.) – Peter Cordes May 15 '18 at 00:52
  • Would like to know more about that if you got any links. – Evan Carroll May 15 '18 at 00:56
  • 1
    @EvanCarroll: [Loading program from RAM in 8086](https://stackoverflow.com/posts/comments/65573239) has something about how 8086 decodes. http://www.cosc.brocku.ca/~bockusd/3p92/Local_Pages/8086_achitecture.htm. You could fill a whole 64k code segment with one giant instruction with repeated prefixes and 8086 would decode it just fine; so clearly it works through prefixes and just sets a flag for the most recently seen prefix of each of the 4 classes (lock, rep, segment override, and um maybe 8086 only has 3, since it doesn't have address-size or operand-size). – Peter Cordes May 15 '18 at 01:05