Intel 8086 opcodes - CP/M

This is a discussion on Intel 8086 opcodes - CP/M ; B'ichela wrote: > Just a quick question. of the Major processors used in Home PCs from > the 4004, 8008, 8080,8086 (I doubt this one), 6502, 6510 and 6809 > which chip is the closes to RISC? I know what ...

+ Reply to Thread
Page 2 of 4 FirstFirst 1 2 3 4 LastLast
Results 21 to 40 of 65

Thread: Intel 8086 opcodes

  1. Re: RISC vs CISC Re: Intel 8086 opcodes

    B'ichela wrote:

    > Just a quick question. of the Major processors used in Home PCs from
    > the 4004, 8008, 8080,8086 (I doubt this one), 6502, 6510 and 6809
    > which chip is the closes to RISC? I know what Risc stands for "Reduced
    > Instruction Set Code" but from the practical standpoint what defines a
    > Risc chip?


    Among others are fixed size, or a small number sizes of instructions,
    and simple addressing modes. Usually a load/store architecture.
    That is, load and store to memory, all operations are between
    registers.

    > The 6502 had less than 200 instructions (thats from memory
    > and I could be wrong), the 6809 had about 1064 of them in total. and
    > given what I am reading of the 8086, its loaded to the gills with
    > instructions.


    Are you including different addressing modes in the instruction count?

    There was a trend for a while in making more complex instructions
    to simplify life for assembly programmers. When it was found that
    compilers didn't need those, the RISC idea was formed.

    -- glen


  2. Re: RISC vs CISC Re: Intel 8086 opcodes

    On Mon, 03 Sep 2007 19:13:55 +0100, David Given
    wrote:

    >no.spam@no.uce.bellatlantic.net wrote:
    >[...]
    >> Total number of instructions is not a definate criteria. USually RISC
    >> designs were more biased by simple archetectures that were very fast
    >> (for there time) that executed simple instructions in or or two clock
    >> cycles max. SPARC, ARM are RISC examples and 8086, 6809, 68000,
    >> PSP11 and VAX are examples of CISC.

    >
    >OTOH the PowerPC, which is marketed as RISC, has about 300 instructions, more
    >than the uncontroversially CISC 8080 and 6502; and while the 68000 is CISC,
    >the Coldfire, which uses *exactly the same instruction set* [1], is RISC!


    A large instruction set is usually a function of instruction word
    size.

    >These days I reckon that modern processor design has taken on board the good
    >features of both the classic RISC *and* CISC designs, and as a result the
    >terms don't mean much any more.
    >
    >


    I'd argue that the one instuction per clock cycle is a significant
    part of the criteria.

    >[1] Okay, okay, not quite exactly. The Coldfire actually uses a subset of the
    >68000 opcodes. However, it's such a large subset that people have been
    >building binary-compatible Amiga clones using Coldfire processors. I have no
    >idea how *anyone* can consider these things RISC.


    Likely because of the small number of clock cycles needed to execute
    an instruction compared to any varient of the 68k.

    In it's heyday of usage RISC and MIPS(millions of instructions per
    second) usually were associated with raw speed.

    How about DEC Alpha wich is supposedly RISC but can run soft emulation
    code to run VAX a notably CISC machine?

    After the mid 90s between sophisticated compilers and increasingly
    sophisticated archetectures the distincion of RISC still stands
    against noticeably CISC machines.

    For me processors like 6502 were near RISC and proved simple and
    moderatly fast is viable against complex of the same general computing
    speed. What drove RISC in the 80s was for a given silicon
    foundary capability a die could have only so many transistors and
    with that upper limit complexity or speed was the trade. So the ARM,
    SPARC and other similar designs were cheap to build silicon, fast and
    for the number of transistors on the die small.

    As to reduced instruction sets, I still hold the PDP8 cut it to the
    bone and still proved to be effective. In it's day it was trying to
    reduce the amount of logic (transistors!) required to make a viable
    machine. Nearly 20years later the proces repeats itself as how
    many transistors on a die.


    Allison



  3. Re: RISC vs CISC Re: Intel 8086 opcodes

    no.spam@no.uce.bellatlantic.net wrote:

    (snip)

    >>OTOH the PowerPC, which is marketed as RISC, has about 300 instructions, more
    >>than the uncontroversially CISC 8080 and 6502; and while the 68000 is CISC,
    >>the Coldfire, which uses *exactly the same instruction set* [1], is RISC!


    Instruction count isn't a very good measure. You could be CISC with
    a very small number of instructions and a large number of instruction
    modifiers.

    I would say that the 6502 and 8080 should be in a different class
    altogether. CISC uses a lot of logic, often with microcode, to
    implement complex operations. (Even floating point was pretty
    complex for a 360/40.) RISC uses a lot of transistors to do simple
    operations fast, often with many registers. For the 8080 and 6502,
    I would say the goal wasn't fast, but to do useful operations at all.

    One I still remember is that the 6502 CALL doesn't store the address
    of the next instruction, but one byte earlier.

    > A large instruction set is usually a function of instruction word
    > size.


    >>These days I reckon that modern processor design has taken on board the good
    >>features of both the classic RISC *and* CISC designs, and as a result the
    >>terms don't mean much any more.


    > I'd argue that the one instuction per clock cycle is a significant
    > part of the criteria.


    I agree, though I don't know that it was the right way. That included
    leaving multiply and divide out of early processors (and not so early
    ones) because they couldn't be done in one cycle.

    >>[1] Okay, okay, not quite exactly. The Coldfire actually uses a subset of the
    >>68000 opcodes. However, it's such a large subset that people have been
    >>building binary-compatible Amiga clones using Coldfire processors. I have no
    >>idea how *anyone* can consider these things RISC.


    > Likely because of the small number of clock cycles needed to execute
    > an instruction compared to any varient of the 68k.


    > In it's heyday of usage RISC and MIPS(millions of instructions per
    > second) usually were associated with raw speed.


    MIPS - Meaningless Indicator of Processor Speed.

    > How about DEC Alpha wich is supposedly RISC but can run soft emulation
    > code to run VAX a notably CISC machine?


    That doesn't seem quite fair. Any good machine can emulate most
    other machines. Alpha does have an advantage in hardware
    support for VAX floating point formats, though.

    > After the mid 90s between sophisticated compilers and increasingly
    > sophisticated archetectures the distincion of RISC still stands
    > against noticeably CISC machines.


    > For me processors like 6502 were near RISC and proved simple and
    > moderatly fast is viable against complex of the same general computing
    > speed. What drove RISC in the 80s was for a given silicon
    > foundary capability a die could have only so many transistors and
    > with that upper limit complexity or speed was the trade. So the ARM,
    > SPARC and other similar designs were cheap to build silicon, fast and
    > for the number of transistors on the die small.


    I would say that even the 6502 has too many address modes, and
    too variable instruction length, but definitely is low in transistors.

    For RISC, I see the goal not as low transistors but the most
    processing for a given number of transistors. RISC is often
    register rich. The CDP1802 would probably be the most RISC-like
    of the early generation microprocessors.

    > As to reduced instruction sets, I still hold the PDP8 cut it to the
    > bone and still proved to be effective. In it's day it was trying to
    > reduce the amount of logic (transistors!) required to make a viable
    > machine. Nearly 20years later the proces repeats itself as how
    > many transistors on a die.


    I agree, the PDP-8 does seem RISC like.

    In one of Knuth's books there is discussion of a two instruction
    machine.

    -- glen


  4. Re: RISC vs CISC Re: Intel 8086 opcodes

    On 2007-09-04, glen herrmannsfeldt wrote:
    > no.spam@no.uce.bellatlantic.net wrote:
    >> As to reduced instruction sets, I still hold the PDP8 cut it to the
    >> bone and still proved to be effective. In it's day it was trying to
    >> reduce the amount of logic (transistors!) required to make a viable
    >> machine. Nearly 20years later the proces repeats itself as how
    >> many transistors on a die.

    >
    > I agree, the PDP-8 does seem RISC like.


    Much as I love the sleek, simple, PDP-8 instruction set, have you folks
    considered all the work that has to go on for something like
    JSR I Z 10?

    - Fetch instruction
    - Fetch Z 10
    - Write incremented Z 10
    - Write return address

    Not exactly the RISC ideal. When I though about it a few years ago, it
    looked to me like you'd need five-ported memory to execute a PDP-8
    instruction in one cycle. But then, I might have been fiddling with the
    PDP-5, which stores the PC at location 0...

    > In one of Knuth's books there is discussion of a two instruction
    > machine.


    If you spend some time with Google, you can find some folks who have
    played with a single instruction: subtract and branch on borrow.

    Another scheme I've seen involved a single instruction that moved a word
    in a byte-addressed machine. Addition was performed by constructing
    suitable tables. Branches were done by making the PC addressable. Most
    practical MOVE machines that I've seen discussed (like the British DEUCE
    of the '50s) simply moved the opcode into the address space, so I'm not
    really certain they count.
    --
    roger ivie
    rivie@ridgenet.net

  5. Re: Intel 8086 opcodes

    roche182@laposte.net wrote:
    [snip]

    > 80h = 1000 0000
    > 81h = 1000 0001
    > 82h = 1000 0010
    > 83h = 1000 0011
    >
    > Time to re-read the book.
    >
    > The ADD instruction (Figure 3.18) performs a byte or word
    > addition of the contents of the source and destination operands,
    > and stores the result back in the destination operand. One of
    > the operands can be in a register or in memory (MOD and R/M
    > field); the other operand can be in a register (REG field) or in
    > the instruction (IMMediate field). Both a general form and a
    > short form of the immediate-operand ADD instruction are
    > provided.
    >
    > +-------------+---+---+ +-----+-----+-----+
    > | 0 0 0 0 0 0 | d | w | | mod | reg | r/m |
    > +-------------+---+---+ +-----+-----+-----+
    > ADD: add register/memory with register to either
    >
    > +--------+---+---+ +-----+-----+-----+ +------+ +------------------+
    > | 100000 | s | w | | mod | 000 | r/m | | data | | data if S,W = 01 |
    > +--------+---+---+ +-----+-----+-----+ +------+ +------------------+
    > ADD: add immediate with register/memory to register/memory
    >
    > +---------------+---+ +------+ +---------------+
    > | 0 0 0 0 0 1 0 | w | | data | | data if W = 1 |
    > +---------------+---+ +------+ +---------------+
    > ADD: add immediate with accumulator to accumulator
    >
    > Figure 3.18 Formats of ADD instruction
    >

    [snip]
    The 8086 Book by Rector and Alexy, page 3-65:

    ADD mem/reg,data
    Add Immediate Data to Register or Memory Location

    this instruction is used to add the immediate data present in the
    succeeding program memory byte(s) to the specified register or memory
    location. An 8- or 16-bit operation may be specified.
    The encoding for this instruction is:

    ADD mrm/reg,data
    +------+-+-+ +------------+ +---------+ +---------+
    |100000|s|w| |mod 000 r/m | | kk | | jj |
    +------+-+-+ +------------+ +---------+ +---------+
    ^ ^ ^ ^ ^
    | | | | |
    | | | | +----High-order byte of

    | | | | the 16-bit immediate
    | | | | operand. This byte
    | | | | is only present if
    | | | | s = 0 and w = 1
    | | | +----------------Low-order byte of the
    | | | immediate operand.
    | | | This byte is always
    | | | present.
    | | +-------------------------------Addressing mode
    | | byte(s) as described
    | | earlier in this
    | | Chapter.
    | +---------------------------------------w = 0 8-bit operation
    | w = 1 16-bit operation
    +-----------------------------------------s is the sign

    extension bit. If w =
    0, this bit is
    ignored. If w = 1
    then
    s = 0, all 16 bits of
    the immediate operand
    are present.
    s = 1, only the low-
    order 8 bits of the
    immediate operand are
    present. The high-
    order 8 bits of the
    16 bit operand are
    formed by sign
    extending the high-
    order bit of kk.


    The code for 82 , since the w bit is 0, ignores the sign extension bit,
    so why have an 82? An 80 would be the same.
    Sign extension of an 8 bit operand makes sense, sign extension of a
    16-bit operand doesn't. So for the s bit to be present, the w bit must
    be 1.

    Regards,
    Richard Brady

  6. Re: RISC vs CISC Re: Intel 8086 opcodes

    Roger Ivie wrote:
    [...]
    > If you spend some time with Google, you can find some folks who have
    > played with a single instruction: subtract and branch on borrow.


    Yeah, OISC machines. While they can be implemented with an impressively small
    number of transistors, the memory bandwidth is prohibitive; each 'instruction'
    consists of three words (source address, address of value to subtract, address
    to jump to on borrow) and the 'instructions' are so primitive that you need to
    churn your way through lots of them to achieve anything.

    > Most
    > practical MOVE machines that I've seen discussed (like the British DEUCE
    > of the '50s) simply moved the opcode into the address space, so I'm not
    > really certain they count.


    Indeed. I designed an ISA like this once when I was feeling bored; it exposed
    all the internal devices, and each 'instruction' consisted of
    pick-up-value-at-this-internal-address, write-to-that-internal-address. It
    allowed a number of interesting features, like multiple ALUs and memory access
    devices; but it was extremely interesting that when I tried hand-rolling some
    code for it, the code density was extremely similar to that of traditional
    processors...

    http://www.cowlark.com/nisc.html

    Now all I need to do is to learn enough VHDL to implement one. (Or, more
    likely, discover out why it wouldn't work.)

    --
    ┌── dg*cowlark.com ─── http://www.cowlark.com ──────────────── ──

    │ "There does not now, nor will there ever, exist a programming language in
    │ which it is the least bit hard to write bad programs." --- Flon's Axiom

  7. Re: Intel 8086 opcodes

    Hello, Steve!

    (The following was written last night, before seeing your
    message today.)

    While waiting for the 1981 Intel book (did not arrive today),
    I played a little with the code-macro capability of ASM-86.
    After a few trials, here is what I get:

    ;--------------------------------
    CodeMacro xadd dst:Eb,srcb
    segfix dst
    db 82h
    modrm 0,dst
    db src
    endm
    ;--------------------------------
    0000 82C012 xadd al,12h
    0003 82C112 xadd cl,12h
    0006 82C212 xadd dl,12h
    0009 82C312 xadd bl,12h
    000C 82C412 xadd ah,12h
    000F 82C512 xadd ch,12h
    0012 82C612 xadd dh,12h
    0015 82C712 xadd bh,12h
    ;--------------------------------
    END


    End of assembly. Number of errors: 0. Use factor: 0%

    Hope it will interest you.

    In my comp.os.cpm message, I was thinking that 82 = byte,
    and 83 = word...

    Since then (a very long time!), I have been thinking that,
    instead of the SOURCE operand, the byte/word difference
    could be, in fact, the DESTINATION operand...

    That is to say: both 82 and 83 opcodes are both adding
    an immediate 8-bit value, but 82 adds it to an 8-bit
    register, while 83 adds it to an 16-bit register!

    I cannot wait to receive the 1981 Intel book, to
    know if I am right!


    Yours Sincerely,
    Mr Emmanuel Roche



  8. Re: RISC vs CISC Re: Intel 8086 opcodes

    In article , glen herrmannsfeldt wrote:
    > Are you including different addressing modes in the instruction count?

    In the case of the 6809 I was. not because I was trying to be
    a fool but because the number of instructions/variation of
    instructions stuck in my head at over 1,464. I don't remember how manh
    the 6502 and its kin had.
    >
    > There was a trend for a while in making more complex instructions
    > to simplify life for assembly programmers. When it was found that
    > compilers didn't need those, the RISC idea was formed.

    Given now that the computer compiles programs written in high
    level languages, the neat shortcuts are not as often used. but... Do
    these shortcut instructions really save time in program execution vs
    a compiled program written in C or Pascal? Certainly a compiler could
    make use of the shortcuts if the compiler could be designed to use the
    shortcuts effectivly.

    --

    From the Desk of the Sysop of:
    Planet Maca's Opus, a Free open BBS system. telnet://pinkrose.dhis.org
    Web Site: http://pinkrose.dhis.org, Dialup 860-618-3091 300-33600 bps
    The New Cnews maintainer
    B'ichela


  9. Re: RISC vs CISC Re: Intel 8086 opcodes

    B'ichela wrote:

    (snip)

    > Given now that the computer compiles programs written in high
    > level languages, the neat shortcuts are not as often used. but... Do
    > these shortcut instructions really save time in program execution vs
    > a compiled program written in C or Pascal? Certainly a compiler could
    > make use of the shortcuts if the compiler could be designed to use the
    > shortcuts effectivly.


    I could crosspost to comp.compilers, but...

    It is easy to use a dynamic programming algorithm in a compiler to
    select the optimal instruction sequence if you can put a cost to each
    instruction or instruction group. What is easy for a compiler may not
    be so easy for a person, and vice versa.

    Also, when memory was more expensive there was more need for
    compact instructions sets, another advantage for CISC.
    VAX is said to have been designed to reduce code size at the
    expense of complex instructions. Some examples are a bounds
    check instruction for array access and POLY to evaluate a
    polynomial. On some processors those were slower than doing
    the operation using separate instructions!

    -- glen


  10. Re: RISC vs CISC Re: Intel 8086 opcodes

    In article
    mdalene@pinkrose.dhis.org "B'ichela" writes:

    > In article , glen herrmannsfeldt
    > wrote:
    > > Are you including different addressing modes in the instruction count?

    > In the case of the 6809 I was. not because I was trying to be
    > a fool but because the number of instructions/variation of
    > instructions stuck in my head at over 1,464. I don't remember how manh
    > the 6502 and its kin had.


    It's years since I worked with a 6502 but seem to recall there
    were only around 40 or 50 instructions. The 6811 I worked on
    more recently had a few more for the additional accumulator, but
    the total must have been still firmly in double figures. And
    this latter's instruction set is wonderfully orthogonal.

    Pete
    --
    "We have not inherited the earth from our ancestors,
    we have borrowed it from our descendants."

  11. Re: RISC vs CISC Re: Intel 8086 opcodes

    B'ichela wrote:
    [...]
    > Given now that the computer compiles programs written in high
    > level languages, the neat shortcuts are not as often used. but... Do
    > these shortcut instructions really save time in program execution vs
    > a compiled program written in C or Pascal? Certainly a compiler could
    > make use of the shortcuts if the compiler could be designed to use the
    > shortcuts effectivly.


    Here's an interesting comment I found in the 68000 code generator for theACK:

    /* #define FANCY_MODES 1
    /* On the M68020, there are some real fancy addressing modes.
    Their use makes the code a bit shorter, but also much slower.
    The FANCY_MODES #define enables the use of these addressing
    modes.
    */

    So that author obviously thought not.

    --
    ┌── dg*cowlark.com ─── http://www.cowlark.com ──────────────── ──

    │ "There does not now, nor will there ever, exist a programming language in
    │ which it is the least bit hard to write bad programs." --- Flon's Axiom

  12. Re: Intel 8086 opcodes

    80OPC2.WS4
    ----------

    - "82 opcodes: a bug made in 1978?"

    I have finally received the 1981 Intel manual. I took my pen, a
    sheet of paper, and the Intel "The 8086 Family User's Manual",
    October 1979.

    I systematically compared both manuals: the only differences
    were:

    1) the Device Specifications appendix was different.

    2) the new manual has a supplement, titled "The 8087 Numeric
    Data Processor", so I will finally be able to do some 8087
    programming (until then, I had nothing about it in my
    collection: floating-point doesn't seem to interest many
    persons...).

    So, this manual was a big deception. I compared page-by-page the
    125 pages dealing with the 8086 in both versions: they were
    identical.

    Studying one manual, I noticed that they have a 16x16 opcode
    matrix, like "The 8086 Primer" (the book authored by one of the
    authors of the 8086 CPU) but, BIG DIFFERENCE: before this
    matrix, there is "Machine Instruction Decoding Guide", giving
    each 8086 opcode in hex (for the opcode) and binary for the
    MODRM byte... (The 8086 primer only contains binary: apparently,
    the author decodes multi-bytes binary patterns at a glance...)
    (and like particularly to "boxes" them in his book)

    With this "Decoding Guide", I checked my I8086.A86 file: they
    now use the same variables.

    While comparing the "Decoding Guide" with the 16x16 matrix (and
    especially its "Secondary Opcode Space" table), I finally
    noticed something...

    The "Primary Opcode Space" table being a 16x16 table filled with
    mnemonics, I simply cannot reproduce it here (since some
    regulars insist that only 64 columns be used). So, you will have
    to understand that the following is portions of the 16x16
    matrix:

    .0 .1 .2 .3
    +-------+-------+-------+-------+--
    8. | Immed | Immed | Immed | Immed | (...)
    | b,r/m | w,r/m | b,r/m | is,r/m|
    +-------+-------+-------+-------+--

    .0 .1 .2 .3
    +-------+-------+-------+-------+--
    D. | Shift | Shift | Shift | Shift | (...)
    | b | w | b,v | w,v |
    +-------+-------+-------+-------+--

    .6 .7 .E .F
    --+-------+-------+-- --+-------+-------+
    F. (...) | Grp 1 | Grp 1 | (...) | Grp 2 | Grp 2 |
    | b,r/m | w,r/m | | b,r/m | w,r/m |
    --+-------+-------+-- --+-------+-------+

    See? I want to draw your attention to opcodes 80-83, D0-D3, F6-
    F7, and FE-FF.

    Why? Because the "Secondary Opcode Space" table is said to
    describe the 2-byte opcodes of the 8086 CPU.

    opc. | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
    ------+-----+-----+-----+-----+-----+-----+-----+-----
    Immed | ADD | OR | ADC | SBB | AND | SUB | XOR | CMP
    ------+-----+-----+-----+-----+-----+-----+-----+-----
    Shift | ROL | ROR | RCL | RCR | SHL*| SHR | --- | SAR (*=SAL)
    ------+-----+-----+-----+-----+-----+-----+-----+-----
    Grp 1 | TEST| --- | NOT | NEG | MUL | IMUL| DIV | IDIV
    ------+-----+-----+-----+-----+-----+-----+-----+-----
    Grp 2 | INC | DEC | CALL| CALL| JMP | JMP | PUSH| ---
    | | | id | L,id| id | L,id| |
    ------+-----+-----+-----+-----+-----+-----+-----+-----

    In our case, it all started when I tried to generate some 82
    opcodes, to check that ASM-86 could produce all the legal 8086
    opcodes. I had no trouble generating the 80, 81, and 83 opcodes
    of ADD but, no matter what I tried, I simply was not able to
    generate the 82 opcode. As I wrote in a short message, using a
    "codemacro" (a feature of ASM-86), I was finally able to
    generate them. By the way, let us review them:

    0122 8006111112 R add mem_8,12h ; 80
    0127 800E111112 R or mem_8,12h ; 80
    012C 8016111112 R adc mem_8,12h ; 80
    0131 801E111112 R sbb mem_8,12h ; 80
    0136 8026111112 R and mem_8,12h ; 80
    013B 802E111112 R sub mem_8,12h ; 80
    0140 8036111112 R xor mem_8,12h ; 80
    0145 803E111112 R cmp mem_8,12h ; 80

    014A 810622225634 R add mem_16,3456h ; 81
    0150 810E22225634 R or mem_16,3456h ; 81
    0156 811622225634 R adc mem_16,3456h ; 81
    015C 811E22225634 R sbb mem_16,3456h ; 81
    0162 812622225634 R and mem_16,3456h ; 81
    0168 812E22225634 R sub mem_16,3456h ; 81
    016E 813622225634 R xor mem_16,3456h ; 81
    0174 813E22225634 R cmp mem_16,3456h ; 81

    017A 82C012 add82 al,12h ; 82
    ; 82 -- mod 001 r/m -- not used
    017D 82C012 adc82 al,12h ; 82
    0180 82C012 sbb82 al,12h ; 82
    ; 82 -- mod 100 r/m -- not used
    0183 82C012 sub82 al,12h ; 82
    ; 82 -- mod 110 r/m -- not used
    0186 82C012 cmp82 al,12h ; 82

    0189 83C512 add bp,12h ; 83
    ; 83 -- mod 001 r/m -- not used
    018C 83D512 adc bp,12h ; 83
    018F 83DD12 sbb bp,12h ; 83
    ; 83 -- mod 100 r/m -- not used
    0192 83ED12 sub bp,12h ; 83
    ; 83 -- mod 110 r/m -- not used
    0195 83FD12 cmp bp,12h ; 83

    Now, what is the problem (now that we can generate 82 opcodes at
    will)?

    The problem is that the "Secondary Opcode Space" table says that
    there are 8 opcodes for "Immed"(iate) values, when opcodes 82
    and 83 visibly only allow 5! QED!

    That is to say: the line for "Immed" correspond to opcodes 80
    and 81, but one line (that we are going to call "Imm5") is
    missing for opcodes 82 and 83:

    opc. | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
    ------+-----+-----+-----+-----+-----+-----+-----+-----
    Imm5 | ADD | --- | ADC | SBB | --- | SUB | --- | CMP
    ------+-----+-----+-----+-----+-----+-----+-----+-----

    And, of course, the "Primary Opcode Space" table needs to be
    updated:

    .0 .1 .2 .3
    +-------+-------+-------+-------+--
    8. | Immed | Immed | Imm5 | Imm5 | (...)
    | b,r/m | w,r/m | b,r/m | is,r/m|
    +-------+-------+-------+-------+--

    Haaaaaa!!! The official Intel doc now reflects the reality...

    But, by the way, the "Seconday Opcode Space" table has 4
    lines... So, what about the other lines?

    The Shift line is good for the D0, D1, D2, and D3 opcodes (as a
    close study of the "Decoding Guide" will reveal).

    The Grp 1 line is good for the F6 and F7 opcodes.

    However, when we reach the end of the opcodes, there is a
    problem: my listing (and the "Decoding Guide") say that:

    0300 FE061111 R inc mem_8
    0304 FE0E1111 R dec mem_8
    ; FE -- mod 010 r/m -- not used
    ; FE -- mod 011 r/m -- not used
    ; FE -- mod 100 r/m -- not used
    ; FE -- mod 101 r/m -- not used
    ; FE -- mod 110 r/m -- not used
    ; FE -- mod 111 r/m -- not used

    0308 FF062222 R inc mem_16
    030C FF0E2222 R dec mem_16
    0310 FFD0 call ax
    0312 FF162222 R call mem_16
    0316 FFE0 jmp ax
    0318 FF262222 R jmp mem_16
    031C FF362222 R push mem_16
    ; FF -- mod 111 r/m -- not used

    That is to say: there are only 2 opcodes starting with FE, but 7
    starting with FF... and, another time, the "Secondary Opcode
    Space" table does not correspond with reality:

    opc. | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
    ------+-----+-----+-----+-----+-----+-----+-----+-----
    Grp 3 | INC | DEC | --- | --- | --- | --- | --- | ---
    ------+-----+-----+-----+-----+-----+-----+-----+-----

    .E .F
    --+-------+-------+
    F. (...) | Grp 3 | Grp 2 |
    | b,r/m | w,r/m |
    --+-------+-------+

    Ha! That's better! I prefer to have my technical documentation
    reflect the reality.

    So, if you are still programming your IBM Clown in 8086
    assembler, the correct "Secondary Opcode Space" table is:

    opc. | 000 | 001 | 010 | 011 | 100 | 101 | 110 | 111
    ------+-----+-----+-----+-----+-----+-----+-----+-----
    Immed | ADD | OR | ADC | SBB | AND | SUB | XOR | CMP
    ------+-----+-----+-----+-----+-----+-----+-----+-----
    Imm5 | ADD | --- | ADC | SBB | --- | SUB | --- | CMP
    ------+-----+-----+-----+-----+-----+-----+-----+-----
    Shift | ROL | ROR | RCL | RCR | SHL*| SHR | --- | SAR (*=SAL)
    ------+-----+-----+-----+-----+-----+-----+-----+-----
    Grp 1 | TEST| --- | NOT | NEG | MUL | IMUL| DIV | IDIV
    ------+-----+-----+-----+-----+-----+-----+-----+-----
    Grp 2 | INC | DEC | CALL| CALL| JMP | JMP | PUSH| ---
    | | | id | L,id| id | L,id| |
    ------+-----+-----+-----+-----+-----+-----+-----+-----
    Grp 3 | INC | DEC | --- | --- | --- | --- | --- | ---
    ------+-----+-----+-----+-----+-----+-----+-----+-----

    (Don't forget to also patch the "Primary Opcode Space" table.)

    All this don't explain why Robert ("Bob") Silberstein introduced
    a "signed byte" type of operand in ASM-86 (used only 5 times in
    a 40 KB program). The only thing I have found is that the
    comment for the 83 opcode is "is,r/m" and "is" is said to mean
    "immediate byte, sign extended". Except that, I have been unable
    to find any reference to a "signed byte" in either "The 8086
    Primer" or "The 8086 Family User's Manual". Many instructions
    have a "integer" and "signed integer" variation, but I have been
    unable to find such a distinction for bytes.


    Yours Sincerely,
    Mr Emmanuel Roche



  13. Re: Intel 8086 opcodes

    82OPC3.WS4
    ----------

    "82 opcodes: the end?"

    For some unknown reason, my last message about the 82 opcodes
    did not seem to generate much response...

    Anyway, I finally have a file able to generate all the legal
    ("legal" in the sense of recognized by ASM-86, since it appears
    that most assemblers do NOT follow exactly the syntax used by
    Intel in 1978... One more "feature" of the IBM Clown!)
    instructions of the 8086 CPU.

    After a while, I was wondering how to test it? The only solution
    was to test it against SID-86, since an assembler is only one
    part of an assembly language development system, whose other
    side is the debugger (how do you debug an assembler without a
    (good) working debugger?). In our case, I got:

    18E8:01A3 ADD BYTE [1111],12
    18E8:01A8 OR BYTE [1111],12
    18E8:01AD ADC BYTE [1111],12
    18E8:01B2 SBB BYTE [1111],12
    18E8:01B7 AND BYTE [1111],12
    18E8:01BC SUB BYTE [1111],12
    18E8:01C1 XOR BYTE [1111],12
    18E8:01C6 CMP BYTE [1111],12

    18E8:01CB ADD WORD [2222],3456
    18E8:01D1 OR WORD [2222],3456
    18E8:01D7 ADC WORD [2222],3456
    18E8:01DD SBB WORD [2222],3456
    18E8:01E3 AND WORD [2222],3456
    18E8:01E9 SUB WORD [2222],3456
    18E8:01EF XOR WORD [2222],3456
    18E8:01F5 CMP WORD [2222],3456

    18E8:01FB ADD AL,12
    18E8:01FE ADC AL,12
    18E8:0201 SBB AL,12
    18E8:0204 SUB AL,12
    18E8:0207 CMP AL,12

    18E8:020A ADD BP,0012
    18E8:020D ADC BP,0012
    18E8:0210 SBB BP,0012
    18E8:0213 SUB BP,0012
    18E8:0216 CMP BP,0012

    (I have added empty lines to separate the various (80, 81, 82,
    and 83) opcodes.)

    The obvious thing to notice is that SID-86 is adding a pair of
    zeroes in front of each byte to be ADDed, etc. to the 16-bit
    register. Since those "00" are not part of the H86 or CMD file,
    this is clearly a bug (that will have to be removed).

    Note also the "BYTE [xxxx]" and "WORD [xxxx]" added by SID-86:
    they were not present in the A86 file, which contained only
    "mem_8" and "mem-16", following the Intel "Machine Instruction
    Decoding Guide". As already noted, everything in the 8086 is
    very verbose, and I simply don't know if we should keep this
    "feature" since, if we debug our programs, we would have the
    source code nearby, to find where was the bug. On the other
    hand, this display tells us whether the variable was a DB or a
    DW, so maybe it is worthwhile? (If you have an opinion on this,
    you are welcome.)

    I had also commented on the stupidity of having multiple
    mnemonics generating the same opcode. For instance, SID-86
    displays:

    18E8:016B JB 0167
    18E8:016D JB 0167
    18E8:016F JB 0167
    18E8:0171 JNB 0167
    18E8:0173 JNB 0167
    18E8:0175 JNB 0167
    18E8:0177 JZ 0167
    18E8:0179 JZ 0167
    18E8:017B JNZ 0167
    18E8:017D JNZ 0167
    18E8:017F JBE 0167
    18E8:0181 JBE 0167
    18E8:0183 JA 0167
    18E8:0185 JA 0167
    18E8:0187 JS 0167
    18E8:0189 JNS 0167
    18E8:018B JP 0167
    18E8:018D JP 0167
    18E8:018F JNP 0167
    18E8:0191 JNP 0167
    18E8:0193 JL 0167
    18E8:0195 JL 0167
    18E8:0197 JNL 0167
    18E8:0199 JNL 0167
    18E8:019B JLE 0167
    18E8:019D JLE 0167
    18E8:019F JG 0167
    18E8:01A1 JG 0167

    18E8:030D LOOPNE 030D
    18E8:030F LOOPNE 030D
    18E8:0311 LOOPE 030D
    18E8:0313 LOOPE 030D

    18E8:0334 REPNE NOP
    18E8:0336 REPNE NOP
    18E8:0338 REP NOP
    18E8:033A REP NOP
    18E8:033C REP NOP

    So, my opinion is reinforced: it is totally crazy to have an
    assembler use mnemonics that are NEVER to be displayed by the
    debugger! When I started, one common wisdom was: "Garbage in,
    garbage out". And, the only way I can see to remove this garbage
    is to remove those useless mnemonics in the future version of
    ASM-86... (At least, this will free some space.)

    Finally, I have written, somewhere: "the 32 2-bytes of the 8086
    CPU". After having finally managed to spot the error in the
    "Secondary Opcode Space" table, I had doubts about this value...
    So, let us study what we now know:

    80 opcodes --> Immed --> 8 2-bytes opcodes
    81 --> Immed --> 8
    82 --> Imm5 --> 5
    83 --> Imm5 --> 5

    D0 --> Shift --> 7
    D1 --> Shift --> 7
    D2 --> Shift --> 7
    D3 --> Shift --> 7

    F6 --> Grp 1 --> 7
    F7 --> Grp 1 --> 7

    FE --> Grp 3 --> 2
    FF --> Grp 2 --> 7

    Total: 77 2-bytes 8086 opcodes

    Now, this is not the end of the story, since there are simply
    blanks in the official Intel 8086 "Machine Instruction Decoding
    Guide". The following opcodes: 0F, 60-6F, C0, C1, C8, C9, D6,
    and F1 are not even documented as "not used" or "reserved": they
    are simply "holes" in the instruction set! (Yet another
    "feature" of this CPU!) (By the way, if anybody out there knows
    what Intel made of them, later, he is welcome.)

    So, on a byte, you can have 256 opcodes. There are 23 "holes"
    opcodes. Our investigation of the "Secondary Opcode Space" table
    involved 12 opcodes ( 4 + 4 + 2 + 2 = 4 * 3 = 12). Those "holes"
    and "secondary opcodes" are, obviously, not one byte long
    opcodes. So, 23 + 12 = 35 opcodes to remove from 256 = 256 -35 =
    221 one-byte long opcodes. To those one-byte long opcodes, we
    can add the 77 two-bytes long opcodes just listed. Total: the
    Intel 8086 CPU has 298 "legal" opcodes.

    This may not seem big. However, to some Old Timers who remember
    that the Zilog Z-80 had 144 documented instructions (there were
    an additional hundred undocumented opcodes...), those 144
    instructions were generating some 820 (or was it 916?)
    opcodes... So, with so many 8086 instructions dealing with 16-
    bit values, checking that a 8086 debugger was really recognizing
    correctly all the "legal" bit patterns could be quite
    difficult... (In fact, we have just demonstrated a bug in SID-86
    Version 3.2...)

    Me, when I disassembled ZSID Version 2.5, I made a file
    containing all the legal Z-80 opcodes. Since I could not find
    any assembler able to generate them (remember, some hundred
    opcodes are undocumented!), I ended using a file containing only
    DB statements, so that any assembler could assemble it.
    Fortunately, the Z-80 instruction set being so regular, I could
    use BASIC to produce pages after pages (the final version of the
    test file was 20 pages long) of opcodes. Is it a waste of time,
    checking a debugger? In my case, I found 4 bugs in ZSID Version
    2.5...

    (Knowing the kind of job to do, and thinking what will need to
    be done on this 8086 debugger, I tremble!)


    Yours Sincerely,
    Mr Emmanuel Roche



  14. Re: Intel 8086 opcodes

    On Tue, 11 Sep 2007 07:29:17 -0700, roche182@laposte.net wrote:

    >82OPC3.WS4
    >----------
    >
    >"82 opcodes: the end?"
    >
    >For some unknown reason, my last message about the 82 opcodes
    >did not seem to generate much response...


    It's an 80x86 archetecture discussion not really CP/M.

    Any programmer knows 90% or so of real work is done with far
    less than 80% of the instruction set. Some few percent of the
    instructions are often best found in the rare if every used pile and
    would not be missed if deleted.

    ------->x86 stuff deleted.<---------------


    >This may not seem big. However, to some Old Timers who remember
    >that the Zilog Z-80 had 144 documented instructions (there were
    >an additional hundred undocumented opcodes...), those 144
    >instructions were generating some 820 (or was it 916?)
    >opcodes...


    The Z80 has 158 instructions according to Zilog and also their
    publications. That does not include the Z180 and Z280 that extend the
    instruction set further.

    The 8086 stuff is better served in Alt.Arch.intel.x86.

    >Me, when I disassembled ZSID Version 2.5, I made a file
    >containing all the legal Z-80 opcodes. Since I could not find
    >any assembler able to generate them (remember, some hundred
    >opcodes are undocumented!), I ended using a file containing only
    >DB statements, so that any assembler could assemble it.
    >Fortunately, the Z-80 instruction set being so regular, I could
    >use BASIC to produce pages after pages (the final version of the
    >test file was 20 pages long) of opcodes. Is it a waste of time,
    >checking a debugger? In my case, I found 4 bugs in ZSID Version
    >2.5...
    >


    There are several lists of Z80 "undocumented" instructions and the
    analysis. The good news is everybody elses Z80 executes them
    completely and faithfully.

    A few moments reading available docuuments on line would
    reveal this.


    Allison

  15. Re: Intel 8086 opcodes

    On Sep 6, 3:27 am, roche...@laposte.net wrote:
    > 80OPC2.WS4
    > ----------
    >
    > - "82 opcodes: a bug made in 1978?"


    More like poor documentation, a notorious 'feature' of intel docs
    in general.

    > That is to say: there are only 2 opcodes starting with FE, but 7
    > starting with FF... and, another time, the "Secondary Opcode
    > Space" table does not correspond with reality:
    >


    >
    > Ha! That's better! I prefer to have my technical documentation
    > reflect the reality.
    >

    Yes, good catch.. this is separated in the later 486 manual for
    example, as:
    FE := Grp4 INC/DEC
    FF := Grp5 INC/DEC

    >
    > All this don't explain why Robert ("Bob") Silberstein introduced
    > a "signed byte" type of operand in ASM-86 (used only 5 times in
    > a 40 KB program). The only thing I have found is that the
    > comment for the 83 opcode is "is,r/m" and "is" is said to mean
    > "immediate byte, sign extended". Except that, I have been unable
    > to find any reference to a "signed byte" in either "The 8086
    > Primer" or "The 8086 Family User's Manual". Many instructions
    > have a "integer" and "signed integer" variation, but I have been
    > unable to find such a distinction for bytes.
    >

    But you know the signed byte significance, +127, -128.

    The issue here is that the source is a signed byte, but the
    destination
    is word_sized, so..

    83 nn OP Reg16|Mem16,signed Immed8

    assures sign extention into the larger destination. I wonder how many
    subtle bugs involve this detail being missed.

    Steve

    > Yours Sincerely,
    > Mr Emmanuel Roche




  16. Re: Intel 8086 opcodes

    ESCAPE2.WS4
    -----------

    As we saw in the last message, there is an unresolved problem
    with the 8086 ESC instruction.

    SID-86 3.2 RASM-86 1.4A
    ------------ ------------
    ESC 00,AL esc 0,al
    ESC 08,CX <--- ?? ---> esc 8,cl
    ESC 10,DL esc 16,dl
    ESC 18,BX <--- ?? ---> esc 24,bl
    ESC 20,AH esc 32,ah
    ESC 28,BP <--- ?? ---> esc 40,ch
    ESC 30,DH esc 48,dh
    ESC 38,DI <--- ?? ---> esc 56,bh

    The problem with this bug (?) is that the ESC instruction is
    little interstood, since it was intended to be a mechanism by
    which the 8086 CPU could "share" instructions with a co-
    processor and (1) only the 8087 used this mechanism, (2) it was
    found that a bad 8087 opcode could hang the whole system (the
    original mechanism was providing for only 64 additional
    instructions, but the 8087 ended by using 2 bytes for its
    opcode...), so later Intel numerical data processor use another
    way to get their commands from the CPU.

    So, in a sense, this discussion is outdated, since our sample
    coding uses 2 bytes, while now Intel CPUs use 3 bytes to
    communicate with their NDPs. In addition, if you wanted to use
    the ESC mechanism, you would need to build your own motherboard
    with a 8086 CPU, since Intel CPUs now incorporate the NDP inside
    the same chip...

    Anyway, the subject is so technical that we'd better have a look
    to "The 8086 Primer (2nd Edition)":

    The subordinate processor operates by watching the 8086 and
    being constantly aware of the instruction being executed. In
    particular, it is watching for the special instruction ESCape,
    which is the embodiement of all instructions that the 8086 needs
    help executing. The ESC instruction has a 3-bit field (X)
    indicating which subordinate processor is needed, and a 3-bit
    field (Y) indicating the instruction that processor should
    execute. Both of these fields are ignored by the 8086 processor.
    (This description is slightly simplified; in reality, the six
    ignored bits may arbitrarily be used to distinguish 64
    combinations of processor and/or instruction.) Furthermore, the
    ESC instruction has a MOD field and an R/M field that designate
    a memory operand for the subordinate processor. These two fields
    are, indeed, used by the 8086; the 8086 computes the memory
    address of the operand, and then actually reads the value of the
    operand from memory, although it ignores the value when it gets
    it. The subordinate processor is watching all this, and now
    knows the address of the operand, as well as the value of the
    operand. The subordinate processor now has everything it needs
    (instruction and operand) in order to execute the required
    operation.

    The form of the ESC instruction is shown in Figure 3.48.

    +-----------+---+ +-----+---+-----+
    | 1 1 0 1 1 | x | | mod | y | r/m |
    +-----------+---+ +-----+---+-----+
    ESC: escape

    Figure 3.48

    Ok. We just need to keep in mind that the X and Y fields are 3
    bits wide, so a better figure would be:

    +-----------+-------+ +-----+-------+-----+
    | 1 1 0 1 1 | x x x | | mod | y y y | r/m |
    +-----------+-------+ +-----+-------+-----+
    ESC: escape

    Now, let us look to the problematic opcodes:

    esc 0,al = D8 C0 = 11011 000 11 000 000
    esc 8,cl = D9 C1 = 11011 001 11 000 001
    esc 16,dl = DA C2 = 11011 010 11 000 010
    esc 24,bl = DB C3 = 11011 011 11 000 011
    esc 32,ah = DC C4 = 11011 100 11 000 100
    esc 40,ch = DD C5 = 11011 101 11 000 101
    esc 48,dh = DE C6 = 11011 110 11 000 110
    esc 56,bh = DF C7 = 11011 111 11 000 111

    Whew! Let us now study those bit patterns. "The 8086 Primer"
    does not contain one single line of assembly language
    (apparently, its author only works in binary). The only "coding
    sample" I could find is in "The 8086 Family User's Manual", and
    consists only of the following 2 lines:

    esc 6,array[si]
    esc 20,al

    Assembling them, we get:

    D8 B4 34 12 esc 6,array[si]
    DA E0 esc 20,al

    Let us start by the simpler opcode:

    DA E0 = 11011 010 11 100 000
    ----- --- --- --- ---
    ESC X MOD Y R/M

    Let see... 20 = 10100b and X=010 and Y=100, so XY = 010100b. The
    000b in R/M can mean "AL" if W=0.

    Since Y is only 3 bits wide, let us assemble a few ESC
    instructions:

    ESC X MOD Y R/M
    ----- --- --- --- ---
    D8C0 11011 000 11 000 000 esc 0,al
    D8C8 11011 000 11 001 000 esc 1,al
    D8D0 11011 000 11 010 000 esc 2,al
    D8D8 11011 000 11 011 000 esc 3,al
    D8E0 11011 000 11 110 000 esc 4,al
    D8E8 11011 000 11 101 000 esc 5,al
    D8F0 11011 000 11 110 000 esc 6,al
    D8F8 11011 000 11 111 000 esc 7,al

    D9C0 11011 001 11 000 000 esc 8,al
    DAC0 11011 010 11 000 000 esc 16,al
    DBC0 11011 011 11 000 000 esc 24,al
    DCC0 11011 100 11 000 000 esc 32,al
    DDC0 11011 101 11 000 000 esc 40,al
    DEC0 11011 110 11 000 000 esc 48,al
    DFC0 11011 111 11 000 000 esc 56,al

    DFC8 11011 111 11 001 000 esc 57,al
    DFD0 11011 111 11 010 000 esc 58,al
    DFD8 11011 111 11 011 000 esc 59,al
    DFE0 11011 111 11 100 000 esc 60,al
    DFE8 11011 111 11 101 000 esc 61,al
    DFF0 11011 111 11 110 000 esc 62,al
    DFF8 11011 111 11 111 000 esc 63,al

    It works! So, the famous 0-63 range is coded using the X and Y
    fields contiguously. (Isn't this 8086 CPU wonderful, with its
    opcodes and operands split into 2? In France, we have a saying
    that I did not manage to find in my English dictionaries:
    "Pourquoi faire simple, alors qu'il est si facile de faire
    complique?" (Why make it simple, when it is so easy to make it
    complex?). Obviously, the "designer" of this CPU had this turn
    of mind.)

    Now that we know were are stored the 0-63 range, let us turn our
    attention to the register. (By the way, did you notice that all
    the MOD bits encountered so far are "11", that is to say:
    register mode (no displacement)?)

    0032 D8C0 esc 0,al
    0034 D8C1 esc 0,cl
    0036 D8C2 esc 0,dl
    0038 D8C3 esc 0,bl
    003A D8C4 esc 0,ah
    003C D8C5 esc 0,ch
    003E D8C6 esc 0,dh
    0040 D8C7 esc 0,bh

    0042 D8C0 esc 0,ax
    0044 D8C1 esc 0,cx
    0046 D8C2 esc 0,dx
    0048 D8C3 esc 0,bx
    004A D8C4 esc 0,sp
    004C D8C5 esc 0,bp
    004E D8C6 esc 0,si
    0050 D8C7 esc 0,di

    0052 D8C0 esc 0,es
    0054 D8C1 esc 0,cs
    0056 D8C2 esc 0,ss
    0058 D8C3 esc 0,ds

    ??? Could it be possible that only 8-bit registers are allowed?

    Time to have a look to the other "coding sample":

    D8 B4 34 12 esc 6,array[si]

    ESC X MOD Y R/M Addr.
    ----- --- --- --- --- ------
    D8 B4 34 12 11011 000 10 110 100 (etc.) esc 6,array[si]

    XY = 000110b = 6. MOD=10 = Memory Mode, 16-bit displacement
    follows, so it is normal to have the 34 12 bytes after. R/M=100
    = (SI)+D16 according to the "R/M Field Encoding" table. Indeed,
    we have a "si" in [si], and an address (D16) in "array" (just a
    DB statement in my A86 file). This gives me an idea: let us
    check the values found in the "R/M Field Encoding" table for
    MOD=10.

    0000 D8B03412 R esc 6, array[bx+si]
    0004 D8B13412 R esc 6, array[bx+di]
    0008 3ED8B23412 R esc 6, array[bp+si]
    000D 3ED8B33412 R esc 6, array[bp+di]
    0012 D8B43412 R esc 6, array[si]
    0016 D8B53412 R esc 6, array[di]
    001A 3ED8B63412 R esc 6, array[bp]
    001F D8B73412 R esc 6, array[bx]

    Whaow! First thing to notice: all instances of BP are "prefixed"
    with a 3E byte, which means "Data Segment override". Let us put
    them aside for now.

    ESC X MOD Y R/M Addr.
    ----- --- --- --- --- ------
    D8B03412 11011 000 10 110 000 (etc.) esc 6, array[bx+si]
    D8B13412 11011 000 10 110 001 (etc.) esc 6, array[bx+di]
    D8B23412 11011 000 10 110 010 (etc.) esc 6, array[bp+si]
    D8B33412 11011 000 10 110 011 (etc.) esc 6, array[bp+di]
    D8B43412 11011 000 10 110 100 (etc.) esc 6, array[si]
    D8B53412 11011 000 10 110 101 (etc.) esc 6, array[di]
    D8B63412 11011 000 10 110 110 (etc.) esc 6, array[bp]
    D8B73412 11011 000 10 110 111 (etc.) esc 6, array[bx]

    Yes, we finally recognize (in the R/M column) the MOD=10 column
    of the "R/M Field Encoding" table.

    Normally, if we remove "array" from each line, we should get
    MOD=00, but how do you get a MOD=01 (8-bit displacement)?

    Well, well... The only cases where RASM-86 accepted the
    statements are:

    006B D8F6 esc 6, si
    006D D8F7 esc 6, di
    006F D8363412 R esc 6, array
    0073 D8F3 esc 6, bx

    Everything else I tried was flagged as an error. So, let us
    examine the ones that passed:

    ESC X MOD Y R/M Addr.
    ----- --- --- --- --- ------
    D8F6 11011 000 11 110 110 esc 6, si
    D8F7 11011 000 11 110 111 esc 6, di
    D8363412 11011 000 01 110 110 (etc.) esc 6, array
    D8F3 11011 000 11 110 011 esc 6, bx

    Let see... MOD=11 and R/M=110 so esc 6,si is good. MOD=11 and
    R/M=111, so esc 6,di is good. MOD=11 and R/M=011 so esc 6,BX is
    good. But why is MOD=01 (Memory Mode, 8-bit displacement) when I
    was expecting a MOD=00 for a direct address? At least, this gave
    me an idea for MOD=11 (since I already have 3 of them):

    0000 D8F0 esc 6, ax
    0002 D8F1 esc 6, cx
    0004 D8F2 esc 6, dx
    0006 D8F3 esc 6, bx
    0008 D8F4 esc 6, sp
    000A D8F5 esc 6, bp
    000C D8F6 esc 6, si
    000E D8F7 esc 6, di

    It seems to have worked. Let us check them (why cannot this
    bloody IBM Clown do all this drill job?):

    ESC X MOD Y R/M
    ----- --- --- --- ---
    D8F0 11011 000 11 110 000 esc 6, ax
    D8F1 11011 000 11 110 001 esc 6, cx
    D8F2 11011 000 11 110 010 esc 6, dx
    D8F3 11011 000 11 110 011 esc 6, bx
    D8F4 11011 000 11 110 100 esc 6, sp
    D8F5 11011 000 11 110 101 esc 6, bp
    D8F6 11011 000 11 110 110 esc 6, si
    D8F7 11011 000 11 110 111 esc 6, di

    Phew! This is becoming boring... But at least I know how to
    generate the W=1 (word) register values of the "R/M Field
    Encoding" table for MOD=11.

    So, so far, we managed to produce the bit patterns for MOD=11-
    W=0, MOD=11-W=1, and MOD=10. The problem is the last 2 modes: 00
    and 01.

    To be continued?


    Yours Sincerely,
    Mr Emmanuel Roche



  17. Re: Intel 8086 opcodes

    roche182@laposte.net wrote:
    > ESCAPE2.WS4
    > -----------


    > As we saw in the last message, there is an unresolved problem
    > with the 8086 ESC instruction.


    > SID-86 3.2 RASM-86 1.4A
    > ------------ ------------
    > ESC 00,AL esc 0,al
    > ESC 08,CX <--- ?? ---> esc 8,cl
    > ESC 10,DL esc 16,dl
    > ESC 18,BX <--- ?? ---> esc 24,bl
    > ESC 20,AH esc 32,ah
    > ESC 28,BP <--- ?? ---> esc 40,ch
    > ESC 30,DH esc 48,dh
    > ESC 38,DI <--- ?? ---> esc 56,bh


    > The problem with this bug (?) is that the ESC instruction is
    > little interstood, since it was intended to be a mechanism by
    > which the 8086 CPU could "share" instructions with a co-
    > processor and (1) only the 8087 used this mechanism, (2) it was
    > found that a bad 8087 opcode could hang the whole system (the
    > original mechanism was providing for only 64 additional
    > instructions, but the 8087 ended by using 2 bytes for its
    > opcode...), so later Intel numerical data processor use another
    > way to get their commands from the CPU.


    If I (remember,understand) right, the 8086 fetches one byte from
    the target address. It doesn't modify the register indicated, but
    does it ever fetch two bytes? I believe an 8088 will only fetch
    one, as will an 8086 with an odd address. In the case of an
    even address, does the 8086 fetch the whole word, even when only
    one byte is needed? Does a load of al from an even memory
    address do a 16 bit fetch or an 8 bit fetch?

    -- glen


  18. Re: Intel 8086 opcodes

    On Thu, 13 Sep 2007 02:26:00 -0800, glen herrmannsfeldt
    wrote:

    >roche182@laposte.net wrote:
    >> ESCAPE2.WS4
    >> -----------

    >
    >> As we saw in the last message, there is an unresolved problem
    >> with the 8086 ESC instruction.

    >
    >> SID-86 3.2 RASM-86 1.4A
    >> ------------ ------------
    >> ESC 00,AL esc 0,al
    >> ESC 08,CX <--- ?? ---> esc 8,cl
    >> ESC 10,DL esc 16,dl
    >> ESC 18,BX <--- ?? ---> esc 24,bl
    >> ESC 20,AH esc 32,ah
    >> ESC 28,BP <--- ?? ---> esc 40,ch
    >> ESC 30,DH esc 48,dh
    >> ESC 38,DI <--- ?? ---> esc 56,bh

    >
    >> The problem with this bug (?) is that the ESC instruction is
    >> little interstood, since it was intended to be a mechanism by
    >> which the 8086 CPU could "share" instructions with a co-
    >> processor and (1) only the 8087 used this mechanism, (2) it was
    >> found that a bad 8087 opcode could hang the whole system (the
    >> original mechanism was providing for only 64 additional
    >> instructions, but the 8087 ended by using 2 bytes for its
    >> opcode...), so later Intel numerical data processor use another
    >> way to get their commands from the CPU.

    >
    >If I (remember,understand) right, the 8086 fetches one byte from
    >the target address. It doesn't modify the register indicated, but
    >does it ever fetch two bytes? I believe an 8088 will only fetch
    >one, as will an 8086 with an odd address. In the case of an
    >even address, does the 8086 fetch the whole word, even when only
    >one byte is needed? Does a load of al from an even memory
    >address do a 16 bit fetch or an 8 bit fetch?
    >
    >-- glen


    If memory is right the 86 fetches three and the 88 only one.

    However what has been forgotton is the 8089 IOP also hasan interacting
    mechanism like a NDP.

    Allison

  19. Re: Intel 8086 opcodes

    Hello, Steve!

    > The issue here is that the source is a signed byte, but the
    > destination is word_sized, so..
    >
    > 83 nn OP Reg16|Mem16,signed Immed8
    >
    > assures sign extention into the larger destination. I wonder how many
    > subtle bugs involve this detail being missed.


    Hum... Question: Do you think that I should leave it alone?

    My first feeling was to remove the "signed byte" distinction, and to
    replace it with "byte".

    But, then, of course, the sign bit would not be "extended"...

    Damned! All that for 5 bytes out of 40 K! As I said, I could not find
    any instance of a "signed byte" anywhere else in the Intel doc. (It
    would be funny to ask this question to some "gurus"...)

    Opinions welcomed.

    Yours Sincerely,
    Mr Emmanuel Roche



  20. Re: Intel 8086 opcodes

    Hello, Glen!

    > If I (remember,understand) right, the 8086 fetches one byte from
    > the target address. It doesn't modify the register indicated, but
    > does it ever fetch two bytes? I believe an 8088 will only fetch
    > one, as will an 8086 with an odd address. In the case of an
    > even address, does the 8086 fetch the whole word, even when only
    > one byte is needed? Does a load of al from an even memory
    > address do a 16 bit fetch or an 8 bit fetch?


    As I said, isn't the 8086 family wonderful, still raising questions 30
    years later?

    I am writing this from the cybercafe, so have no access to my books.

    However, if I have well understood, the only difference between the
    8086 and the 8088 (that Intel was obliged to introduce 2 years later,
    since everybody was using 8-bit systems at the time. Introducing a 16-
    bit CPU alone, without any 16-bit environment was, of course, crazy.
    Finally, a little company chose the 8088...) is the "size" of the I/O
    words (16 versus 8). Internally, both are reading 16 bits, since they
    are 16-bits CPUs. It is only for I/0 that there is a difference in
    "size". However, as explained previously, there are still quite a lot
    of "single byte" "primary opcode". (Remember that most instructions
    are coded on 6 bits, with a "secondary opcode" (re-re-see my last
    message, where the so-called "MODRM byte" -- its author calls it the
    "secondary opcode" -- is explained at length.) So, it is a 16-bit CPU
    that uses (most of the time) 6-bits instructions, and 77 times 6+3
    bits instructions! Logical, isn't it?

    Yours Sincerely,
    Mr Emmanuel Roche



+ Reply to Thread
Page 2 of 4 FirstFirst 1 2 3 4 LastLast