6

I have an instruction: ADD [BX][SI] + 5FFDH, EABFH and I want to know how it operates exactly on 8086 microprocessors. I've realized that this instruction ADD [BX][SI] + 5FFDH, EABFH, works in this manner:

  1. 2 bytes of data arrive from the data bus and go to the instruction queue.
  2. Data available on the instruction queue goes to the instruction decoder.
  3. Another 2 bytes of data arrive from the data bus and go to the instruction queue.
  4. BX and SI values go to the ALU and it calculates BX + SI
  5. Another 2 bytes of data arrive from the data bus and go to the instruction queue.
  6. BX + SI goes into the ALU as input.
  7. 5FFDH pop from instruction queue and goes to the ALU as input.
  8. ALU calculates BX + SI + 5FFDH.
  9. BX + SI + 5FFDH goes to memory through address bus.
  10. BX + SI + 5FFDH's value comes from memory and goes to the ALU as input.
  11. EABFH pop from instruction queue and goes to the ALU as input.
  12. [BX + SI + 5FFDH] + EABFH is calculated by the ALU.
  13. ???????????

So my question is on step 13. How does the microprocessor know the memory address (BX + SI + 5FFDH) at which the value of [BX + SI + 5FFDH] + EABFH should be written to memory given that the instruction queue is empty and we cannot calculate BX + SI + 5FFDH again?

2
  • 3
    What you're referring to seems to be the "base-indexed addressing mode with displacement"
    – tofro
    Commented Jun 7, 2021 at 12:46
  • 2
    Should have asked it about VAX ADD disp(base)[idx], reg and then it might be retro :-)
    – dave
    Commented Jun 8, 2021 at 1:55

1 Answer 1

7

[Preface: This is a generic CS question, not really 8086specific, and should be moved over to SE]

TL;DR:

How microprocessor knows that memory address (BX + SI + 5FFDH) to send [BX + SI + 5FFDH] + EABFH's value to memory according to empty instruction queue and we cannot calculate BX + SI + 5FFDH again.

Why should it be recalculated? That would be rather stupid. The calculated address gets simply kept in an internal register until writing is issued.

A CPU has many more internal registers than the ones defined as part of the ISA. What they are, and how they are used are implementation specific decisions and not part of the ISA. That's were engineers can get creative to improve performance or speed or both (or cost FWIW :))


It does seem that there is a fundamental lack of understanding how a 8086 operates, so maybe some hints about were to look are appropriate:

First of all: Don't assume, but read the Manual

Section 2.2 starting on page 2-3 nicely describes the over all architecture, including the parallel operation of Bus Interface Unit (BIU) and Execution Unit (EU).

  • The BIU holds
    • Address Generation,
    • the necessary _Registers: (IP and segment registers) and
    • Instruction Queue, while
  • The EU consists of
    • _General Registers,
    • ALU and Flags and ofc.
    • Instruction decode and so on.

There is no 'unified' CPU, but BIU and EU working in parallel. The BIU will fetch data from its IP whenever there is no other request and empty space in the instruction queue. So to start with, the EU will stall until a whole instruction is in the queue - in this case all 4 bytes. It will get all 4 bytes at once. After decoding it will calculate the effective address and put a request to the BIU, which will calculate the memory address from the effective address the CPU has sent, fetch the data and hand it to the EU as soon as the fetch is complete (may be multi access cycles in case of unaligned data). After that the EU will process the data - in this case, add an already read constant and issue subsequent write request with the result.

Or in steps:

  1. BIU fills the Instruction Queue (IQ)
  2. Whenever a whole instruction is fetched it gets handed to the EU
  3. BIU continues to (re)fill the IQ
  4. EU decodes the opcode as well as the mod/rm byte
  5. EU calculates Effective Address (EA)
  6. EU issues a read request with EA to BIU for data
  7. BIU calculates memory address from EA and Segment used
  8. BIU puts Read Request out on the Bus and reads
  9. Data is read
  10. BIU delivers data to EU
  11. BIU continues to fill IQ (if not filled)
  12. EU calculates the result
  13. EU issues a write request using the previous EA and calculated result
  14. EU takes next instruction from IQ (or stalls if there is none)
  15. BIU calculates memory address from EA and Segment used
  16. BIU puts Write Request out on the Bus and reads
  17. Data is written

Again: Keep in mind, these are not strictly sequential steps, but parallel actions of both unit (and the Bus).

For the operation of the EU it's not said that the operation gets calculated in a specific sequence - as long as that sequence used confirms to the defined result. It's up to each implementation to handle them in whatever hardware (and/or microcode) they want to throw at it. There is no law against a three input adder - or two sequential adders able to calculate two registers and one constant in a single cycle.

1
  • 2
    How does the BIU determine when a whole instruction is fetched, and what does it count as a "whole instruction"? Something like add [es:bx+1234h],5678h is seven bytes, but the prefetch buffer on the 8088 is only four. Does the starting opcode and r/m byte get moved to the EU before the fetch of the address displacement, or between the fetch of the address displacement and the immediate operand, or what?
    – supercat
    Commented Jun 7, 2021 at 18:06

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