Intel 8086 opcodes - CP/M

This is a discussion on Intel 8086 opcodes - CP/M ; Is anybody out there who would be interested in starting a thread about the exact patterns of the Intel 8086 opcodes? When disassembling ASM-86 Version 1.1, I could not prevent myself from noticing that it was generating code different from ...

+ Reply to Thread
Page 1 of 4 1 2 3 ... LastLast
Results 1 to 20 of 65

Thread: Intel 8086 opcodes

  1. Intel 8086 opcodes

    Is anybody out there
    who would be interested in starting a thread
    about the exact patterns of the Intel 8086 opcodes?

    When disassembling ASM-86 Version 1.1,
    I could not prevent myself from noticing that
    it was generating code different from RASM 1.4.

    To study where was the difference, I wrote
    an I8086.A86 file...

    Unfortunately, I have not been able to
    generate any of the 82 opcodes...

    What am I missing?

    (The following listing was produced using
    RASM 1.4 under DR-DOS. By the way, anybody
    has a RASM manual? My "Programmer's Utility
    Guide" says that RASM has 25 error messages,
    but when I dump it, I find much more (even one
    in lowercase...) and the 8087 mnemonics,
    which are not mentioned anywhere... Also,
    the EXE file is 4 or 5 years older than the PUG.)

    Yours Sincerely,
    Mr Emmanuel Roche


    ; I8086.A86
    ; ---------
    ;
    ; Intel 8086 opcodes in numerical order.
    ;
    ;--------------------------------
    ; Small Memory model.

    CSEG
    DSEG
    ORG 0100h

    ;--------------------------------
    ORG 1111h
    1111 23 label_b db 23h

    ORG 2222h
    2222 8967 label_w dw 6789h
    ;--------------------------------
    CSEG $
    ;--------------------------------
    adr:
    0000 00061111 R add label_b,al
    0004 01062222 R add label_w,ax
    0008 02061111 R add al,label_b
    000C 03062222 R add ax,label_w
    0010 0412 add al,12h
    0012 055634 add ax,3456h
    0015 06 push es
    0016 07 pop es
    0017 08061111 R or label_b,al
    001B 09062222 R or label_w,ax
    001F 0A061111 R or al,label_b
    0023 0B062222 R or ax,label_w
    0027 0C12 or al,12h
    0029 0D5634 or ax,3456h
    002C 0E push cs
    ; 0F -- pop cs -- not used
    002D 10061111 R adc label_b,al
    0031 11062222 R adc label_w,ax
    0035 12061111 R adc al,label_b
    0039 13062222 R adc ax,label_w
    003D 1412 adc al,12H
    003F 155634 adc ax,3456h
    0042 16 push ss
    0043 17 pop ss
    0044 18061111 R sbb label_b,al
    0048 19062222 R sbb label_w,ax
    004C 1A061111 R sbb al,label_b
    0050 1B062222 R sbb ax,label_w
    0054 1C12 sbb al,12h
    0056 1D5634 sbb ax,3456h
    0059 1E push ds
    005A 1F pop ds
    005B 20061111 R and label_b,al
    005F 21062222 R and label_w,ax
    0063 22061111 R and al,label_b
    0067 23062222 R and ax,label_w
    006B 2412 and al,12h
    006D 255634 and ax,3456h
    0070 2600060000 add es:.0,al
    0075 27 daa
    0076 28061111 R sub label_b,al
    007A 29062222 R sub label_w,ax
    007E 2A061111 R sub al,label_b
    0082 2B062222 R sub ax,label_w
    0086 2C12 sub al,12h
    0088 2D5634 sub ax,3456h
    008B 2E00060000 add cs:.0,al
    0090 2F das
    0091 30061111 R xor label_b,al
    0095 31062222 R xor label_w,ax
    0099 32061111 R xor al,label_b
    009D 33062222 R xor ax,label_w
    00A1 3412 xor al,12h
    00A3 355634 xor ax,3456h
    00A6 3600060000 add ss:.0,al
    00AB 37 aaa
    00AC 38061111 R cmp label_b,al
    00B0 39062222 R cmp label_w,ax
    00B4 3A061111 R cmp al,label_b
    00B8 3B062222 R cmp ax,label_w
    00BC 3C12 cmp al,12h
    00BE 3D5634 cmp ax,3456h
    00C1 00060000 add ds:.0,al ; 3E ???
    00C5 3F aas
    00C6 40 inc ax
    00C7 41 inc cx
    00C8 42 inc dx
    00C9 43 inc bx
    00CA 44 inc sp
    00CB 45 inc bp
    00CC 46 inc si
    00CD 47 inc di
    00CE 48 dec ax
    00CF 49 dec cx
    00D0 4A dec dx
    00D1 4B dec bx
    00D2 4C dec sp
    00D3 4D dec bp
    00D4 4E dec si
    00D5 4F dec di
    00D6 50 push ax
    00D7 51 push cx
    00D8 52 push dx
    00D9 53 push bx
    00DA 54 push sp
    00DB 55 push bp
    00DC 56 push si
    00DD 57 push di
    00DE 58 pop ax
    00DF 59 pop cx
    00E0 5A pop dx
    00E1 5B pop bx
    00E2 5C pop sp
    00E3 5D pop bp
    00E4 5E pop si
    00E5 5F pop di
    ; 60-6F -- not used (8087 instructions)
    disp:
    00E6 70FE 00E6 jo disp
    00E8 71FC 00E6 jno disp
    00EA 72FA 00E6 jb disp ; 72
    00EC 72F8 00E6 jnae disp ; 72
    00EE 72F6 00E6 jc disp ; 72
    00F0 73F4 00E6 jnb disp ; 73
    00F2 73F2 00E6 jae disp ; 73
    00F4 73F0 00E6 jnc disp ; 73
    00F6 74EE 00E6 je disp ; 74
    00F8 74EC 00E6 jz disp ; 74
    00FA 75EA 00E6 jne disp ; 75
    00FC 75E8 00E6 jnz disp ; 75
    00FE 76E6 00E6 jbe disp ; 76
    0100 76E4 00E6 jna disp ; 76
    0102 77E2 00E6 jnbe disp ; 77
    0104 77E0 00E6 ja disp ; 77
    0106 78DE 00E6 js disp
    0108 79DC 00E6 jns disp
    010A 7ADA 00E6 jp disp ; 7A
    010C 7AD8 00E6 jpe disp ; 7A
    010E 7BD6 00E6 jnp disp ; 7B
    0110 7BD4 00E6 jpo disp ; 7B
    0112 7CD2 00E6 jl disp ; 7C
    0114 7CD0 00E6 jnge disp ; 7C
    0116 7DCE 00E6 jnl disp ; 7D
    0118 7DCC 00E6 jge disp ; 7D
    011A 7ECA 00E6 jle disp ; 7E
    011C 7EC8 00E6 jng disp ; 7E
    011E 7FC6 00E6 jnle disp ; 7F
    0120 7FC4 00E6 jg disp ; 7F
    0122 8006111112 R add label_b,12h ; 80
    0127 800E111112 R or label_b,12h ; 80
    012C 8016111112 R adc label_b,12h ; 80
    0131 801E111112 R sbb label_b,12h ; 80
    0136 8026111112 R and label_b,12h ; 80
    013B 802E111112 R sub label_b,12h ; 80
    0140 8036111112 R xor label_b,12h ; 80
    0145 803E111112 R cmp label_b,12h ; 80
    014A 810622225634 R add label_w,3456h ; 81
    0150 810E22225634 R or label_w,3456h ; 81
    0156 811622225634 R adc label_w,3456h ; 81
    015C 811E22225634 R sbb label_w,3456h ; 81
    0162 812622225634 R and label_w,3456h ; 81
    0168 812E22225634 R sub label_w,3456h ; 81
    016E 813622225634 R xor label_w,3456h ; 81
    0174 813E22225634 R cmp label_w,3456h ; 81
    017A 03E8 add bp,ax ; 82
    ; 82 -- mod 001 r/m -- not used
    017C 13E8 adc bp,ax ; 82
    017E 1BE8 sbb bp,ax ; 82
    ; 82 -- mod 100 r/m -- not used
    0180 2BE8 sub bp,ax ; 82
    ; 82 -- mod 110 r/m -- not used
    0182 3BE8 cmp bp,ax ; 82
    0184 83C512 add bp,12h ; 83
    ; 83 -- mod 001 r/m -- not used
    0187 83D512 adc bp,12h ; 83
    018A 83DD12 sbb bp,12h ; 83
    ; 83 -- mod 100 r/m -- not used
    018D 83ED12 sub bp,12h ; 83
    ; 83 -- mod 110 r/m -- not used
    0190 83FD12 cmp bp,12h ; 83
    0193 84061111 R test label_b,al
    0197 85062222 R test label_w,ax
    019B 86061111 R xchg al,label_b
    019F 87062222 R xchg ax,label_w
    01A3 884600 mov [bp],al
    01A6 894600 mov [bp],ax

    01A9 8AC1 mov al,cl
    01AB 8BC1 mov ax,cx
    01AD 8CD8 mov ax,ds
    ; 8C -- xx 1xxxxx -- not used
    01AF 8D061111 R lea ax,label_b
    01B3 8ED8 mov ds,ax
    ; 8E -- xx 1xxxxx -- not used
    01B5 8F062222 R pop label_w
    ; 8F -- xx 001 xx -- not used
    ; 8F -- xx 010 xx -- not used
    ; 8F -- xx 011 xx -- not used
    ; 8F -- xx 100 xx -- not used
    ; 8F -- xx 101 xx -- not used
    ; 8F -- xx 110 xx -- not used
    ; 8F -- xx 111 xx -- not used
    01B9 90 nop
    01BA 91 xchg ax,cx
    01BB 92 xchg ax,dx
    01BC 93 xchg ax,bx
    01BD 94 xchg ax,sp
    01BE 95 xchg ax,bp
    01BF 96 xchg ax,si
    01C0 97 xchg ax,di
    01C1 98 cbw
    01C2 99 cwd
    01C3 9A00000000 R callf adr
    01C8 9B wait
    01C9 9C pushf
    01CA 9D popf
    01CB 9E sahf
    01CC 9F lahf
    01CD A01111 R mov al,label_b
    01D0 A12222 R mov ax,label_w
    01D3 A21111 R mov label_b,al
    01D6 A32222 R mov label_w,ax
    01D9 A4 movsb
    01DA A5 movsw
    01DB A6 cmpsb
    01DC A7 cmpsw
    01DD A812 test al,12h
    01DF A95634 test ax,3456h
    01E2 AA stosb
    01E3 AB stosw
    01E4 AC lodsb
    01E5 AD lodsw
    01E6 AE scasb
    01E7 AF scasw
    01E8 B012 mov al,12h
    01EA B112 mov cl,12h
    01EC B212 mov dl,12h
    01EE B312 mov bl,12h
    01F0 B412 mov ah,12h
    01F2 B512 mov ch,12h
    01F4 B612 mov dh,12h
    01F6 B712 mov bh,12h
    01F8 B85634 mov ax,3456h
    01FB B95634 mov cx,3456h
    01FE BA5634 mov dx,3456h
    0201 BB5634 mov bx,3456h
    0204 BC5634 mov sp,3456h
    0207 BD5634 mov bp,3456h
    020A BE5634 mov si,3456h
    020D BF5634 mov di,3456h
    ; C0 -- not used
    ; C1 -- not used
    0210 C25634 ret 3456h
    0213 C3 ret
    0214 C47E06 les di,6[bp]
    0217 C57606 lds si,6[bp]
    021A C606111112 R mov label_b,12h
    ; C6 -- xx 001 xxx -- not used
    ; C6 -- xx 010 xxx -- not used
    ; C6 -- xx 011 xxx -- not used
    ; C6 -- xx 100 xxx -- not used
    ; C6 -- xx 101 xxx -- not used
    ; C6 -- xx 110 xxx -- not used
    ; C6 -- xx 111 xxx -- not used
    021F C70622225634 R mov label_w,3456h
    ; C7 -- xx 001 xxx -- not used
    ; C7 -- xx 010 xxx -- not used
    ; C7 -- xx 011 xxx -- not used
    ; C7 -- xx 100 xxx -- not used
    ; C7 -- xx 101 xxx -- not used
    ; C7 -- xx 110 xxx -- not used
    ; C7 -- xx 111 xxx -- not used
    ; C8 -- not used
    ; C9 -- not used
    0225 CA5634 retf 3456h
    0228 CB retf
    0229 CC int 3
    022A CD12 int 12h
    022C CE into
    022D CF iret
    022E D0C0 rol al,1
    0230 D0C8 ror al,1
    0232 D0D0 rcl al,1
    0234 D0D8 rcr al,1
    0236 D0E0 sal al,1 ; D0
    0238 D0E0 shl al,1 ; D0
    023A D0E8 shr al,1
    ; D0 -- xx 110 xxx -- not used
    023C D0F8 sar al,1
    023E D1C0 rol ax,1
    0240 D1C8 ror ax,1
    0242 D1D0 rcl ax,1
    0244 D1D8 rcr ax,1
    0246 D1E0 sal ax,1 ; D1
    0248 D1E0 shl ax,1 ; D1
    024A D1E8 shr ax,1
    ; D1 -- xx 110 xxx -- not used
    024C D1F8 sar ax,1
    024E D2C1 rol cl,cl
    0250 D2C9 ror cl,cl
    0252 D2D1 rcl cl,cl
    0254 D2D9 rcr cl,cl
    0256 D2E1 sal cl,cl ; D2
    0258 D2E1 shl cl,cl ; D2
    025A D2E9 shr cl,cl
    ; D0 -- xx 110 xxx -- not used
    025C D2F9 sar cl,cl
    025E D3C1 rol cx,cl
    0260 D3C9 ror cx,cl
    0262 D3D1 rcl cx,cl
    0264 D3D9 rcr cx,cl
    0266 D3E1 sal cx,cl ; D3
    0268 D3E1 shl cx,cl ; D3
    026A D3E9 shr cx,cl
    ; D0 -- xx 110 xxx -- not used
    026C D3F9 sar cx,cl
    026E D40A aam
    0270 D50A aad
    ; D6 -- not used
    ; xlat -- does not work...
    0272 D7 xlat al ; Work with
    a register???
    0273 D8C0 esc 0,al
    0275 D9C1 esc 8,cl
    0277 DAC2 esc 16,dl
    0279 DBC3 esc 24,bl
    027B DCC0 esc 32,al
    027D DDC1 esc 40,cl
    027F DEC2 esc 48,dl
    0281 DFC3 esc 56,bl
    disp2:
    0283 E0FE 0283 loopne disp2 ; E0
    0285 E0FC 0283 loopnz disp2 ; E0
    0287 E1FA 0283 loope disp2 ; E1
    0289 E1F8 0283 loopz disp2 ; E1
    028B E2F6 0283 loop disp2
    028D E3F4 0283 jcxz disp2
    028F E412 in al,12h
    0291 E5FF in ax,0FFh
    0293 E612 out 12h,al
    0295 E7FF out 0FFh,ax
    0297 E866FD 0000 call adr
    029A E963FD 0000 jmp adr
    029D EA00000000 R jmpf adr
    02A2 EBDF 0283 jmps disp2
    02A4 EC in al,dx
    02A5 ED in ax,dx
    02A6 EE out dx,al
    02A7 EF out dx,ax
    02A8 F090 lock nop
    ; F1 -- not used
    02AA F290 repne nop ; F2
    02AC F290 repnz nop ; F2
    02AE F390 rep nop ; F3
    02B0 F390 repe nop ; F3
    02B2 F390 repz nop ; F3
    02B4 F4 hlt
    02B5 F5 cmc
    02B6 F606111112 R test label_b,12h
    ; F6 -- xx 001 xxx -- not used
    02BB F6161111 R not label_b
    02BF F61E1111 R neg label_b
    02C3 F6261111 R mul label_b
    02C7 F62E1111 R imul label_b
    02CB F6361111 R div label_b
    02CF F63E1111 R idiv label_b
    02D3 F70622225634 R test label_w,3456h
    ; F7 -- xx 001 xxx -- not used
    02D9 F7162222 R not label_w
    02DD F71E2222 R neg label_w
    02E1 F7262222 R mul label_w
    02E5 F72E2222 R imul label_w
    02E9 F7362222 R div label_w
    02ED F73E2222 R idiv label_w
    02F1 F8 clc
    02F2 F9 stc
    02F3 FA cli
    02F4 FB sti
    02F5 FC cld
    02F6 FD std
    02F7 FE061111 R inc label_b
    02FB FE0E1111 R dec label_b
    ; FE -- xx 010 xxx -- not used
    ; FE -- xx 011 xxx -- not used
    ; FE -- xx 100 xxx -- not used
    ; FE -- xx 101 xxx -- not used
    ; FE -- xx 110 xxx -- not used
    ; FE -- xx 111 xxx -- not used
    02FF FF062222 R inc label_w
    0303 FF0E2222 R dec label_w
    0307 FF162222 R call word ptr label_w
    030B FF5600 call word ptr 0[bp]
    030E FF262222 R jmp word ptr label_w
    0312 FF6600 jmp word ptr 0[bp]
    0315 FF362222 R push word ptr label_w
    ; FF -- xx 111 xxx -- not used

    ;--------------------------------
    END


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


    EOF


  2. Re: Intel 8086 opcodes

    On Aug 28, 6:25 am, roche...@laposte.net wrote:
    > Is anybody out there
    > who would be interested in starting a thread
    > about the exact patterns of the Intel 8086 opcodes?
    >


    Yes, Hello Emmanuel...

    First, do you have this..?

    http://www.intel.com/design/intarch/manuals/270950.htm

    It has the opcode construction tables in the appendixes. And the 8087
    stuff IIRC.

    > When disassembling ASM-86 Version 1.1,
    > I could not prevent myself from noticing that
    > it was generating code different from RASM 1.4.
    >

    I'm sorry I don't see what you mean. ASM86 outputs a binary form,
    RASM a relocatable form for LINK86.

    > To study where was the difference, I wrote
    > an I8086.A86 file...
    >
    > Unfortunately, I have not been able to
    > generate any of the 82 opcodes...
    >
    > What am I missing?


    Probably at least two things:

    1) The 8086 byte codes are variable length depending on the
    instruction form. {1..6 IIRC for the 8086, more max length for the
    later cpu's}.

    2) The destination address, say for a call or jump, is not hard coded
    into the instruction itself, but the destination's relative offset is,
    that is, the distance from the current instruction makes the
    destination address, the distance is the address encoded into the byte
    code for the (let's say) jump instruction. So, for:

    start: jmp end
    start2: jmp end
    end: nop

    The two instructions 'jmp end' will yield different byte strings
    because 'start:' is further from 'end:' than 'start2:' is.

    Under 1), above, the byte 82h is an information byte about how the
    rest of the instruction is to be interpreted, 82h means immediate byte
    source, with a register or memory destination, operation. Other
    byte[s] determine just what operation, register, or memory.

    Maybe I'm not answering your question, maybe I didn't understand your
    question. It is a start.

    The source to ASM86 is available, I think it is in the DRIPAK.ZIP, but
    most of it is PL/M source. The programmer uses the 'code macro'
    method to construct the byte codes for the instructions.

    You could also research the Netwide Assembler source code written in
    C, but there is alot to wade through. But, using the the appendix and
    sid, is easiest, poke in some bytes and let sid decode it,[list]. Or,
    try some instructions to see how they assemble into byte strings...

    --------------------------------------------------
    *** Symbolic Instruction Debugger *** Release 3.2
    Copyright (c) 1983,1984,1985,1988,1990,1991
    Digital Research, Inc. All Rights Reserved
    --------------------------------------------------

    #f0,+1ff,0
    #x
    AX BX CX DX SP BP SI DI CS DS SS ES
    IP
    --I------ 0000 0000 0000 0000 0000 0000 0000 0000 0BF8 0BF8 0BF8 0BF8
    0100
    ADD [BX+SI],AL =00
    #a0
    0BF8:0000 jmp 100
    0BF8:0003 jmp 100
    0BF8:0006 jmp 100
    0BF8:0009 .
    #d0,f
    0BF8:0000 E9 FD 00 E9 FA 00 E9 F7 00 00 00 00 00 00 00
    00 ................
    #

    So.. the destination of the first jump is 00FDh in distance, the
    second is 00FAh away, the third is 00F7h away.
    E9 FD 00
    E9 FA 00
    E9 F7 00

    see?

    Steve

    >
    > (The following listing was produced using
    > RASM 1.4 under DR-DOS. By the way, anybody
    > has a RASM manual? My "Programmer's Utility
    > Guide" says that RASM has 25 error messages,
    > but when I dump it, I find much more (even one
    > in lowercase...) and the 8087 mnemonics,
    > which are not mentioned anywhere... Also,
    > the EXE file is 4 or 5 years older than the PUG.)
    >
    > Yours Sincerely,
    > Mr Emmanuel Roche
    >





  3. Re: Intel 8086 opcodes

    I think that a more relevant point is that there are different binary
    codes that yield the exact same opcode execution. I don't have an
    example, but different assemblers could and did produce different binary
    from the exact same source, but they would execute the exact same way.
    There were some possible ambiguities in how some instructions could be
    expressed in binary object code.


    s_dubrovich@yahoo.com wrote:
    > On Aug 28, 6:25 am, roche...@laposte.net wrote:
    >> Is anybody out there
    >> who would be interested in starting a thread
    >> about the exact patterns of the Intel 8086 opcodes?
    >>

    >
    > Yes, Hello Emmanuel...
    >
    > First, do you have this..?
    >
    > http://www.intel.com/design/intarch/manuals/270950.htm
    >
    > It has the opcode construction tables in the appendixes. And the 8087
    > stuff IIRC.
    >
    >> When disassembling ASM-86 Version 1.1,
    >> I could not prevent myself from noticing that
    >> it was generating code different from RASM 1.4.
    >>

    > I'm sorry I don't see what you mean. ASM86 outputs a binary form,
    > RASM a relocatable form for LINK86.
    >
    >> To study where was the difference, I wrote
    >> an I8086.A86 file...
    >>
    >> Unfortunately, I have not been able to
    >> generate any of the 82 opcodes...
    >>
    >> What am I missing?

    >
    > Probably at least two things:
    >
    > 1) The 8086 byte codes are variable length depending on the
    > instruction form. {1..6 IIRC for the 8086, more max length for the
    > later cpu's}.
    >
    > 2) The destination address, say for a call or jump, is not hard coded
    > into the instruction itself, but the destination's relative offset is,
    > that is, the distance from the current instruction makes the
    > destination address, the distance is the address encoded into the byte
    > code for the (let's say) jump instruction. So, for:
    >
    > start: jmp end
    > start2: jmp end
    > end: nop
    >
    > The two instructions 'jmp end' will yield different byte strings
    > because 'start:' is further from 'end:' than 'start2:' is.
    >
    > Under 1), above, the byte 82h is an information byte about how the
    > rest of the instruction is to be interpreted, 82h means immediate byte
    > source, with a register or memory destination, operation. Other
    > byte[s] determine just what operation, register, or memory.
    >
    > Maybe I'm not answering your question, maybe I didn't understand your
    > question. It is a start.
    >
    > The source to ASM86 is available, I think it is in the DRIPAK.ZIP, but
    > most of it is PL/M source. The programmer uses the 'code macro'
    > method to construct the byte codes for the instructions.
    >
    > You could also research the Netwide Assembler source code written in
    > C, but there is alot to wade through. But, using the the appendix and
    > sid, is easiest, poke in some bytes and let sid decode it,[list]. Or,
    > try some instructions to see how they assemble into byte strings...
    >
    > --------------------------------------------------
    > *** Symbolic Instruction Debugger *** Release 3.2
    > Copyright (c) 1983,1984,1985,1988,1990,1991
    > Digital Research, Inc. All Rights Reserved
    > --------------------------------------------------
    >
    > #f0,+1ff,0
    > #x
    > AX BX CX DX SP BP SI DI CS DS SS ES
    > IP
    > --I------ 0000 0000 0000 0000 0000 0000 0000 0000 0BF8 0BF8 0BF8 0BF8
    > 0100
    > ADD [BX+SI],AL =00
    > #a0
    > 0BF8:0000 jmp 100
    > 0BF8:0003 jmp 100
    > 0BF8:0006 jmp 100
    > 0BF8:0009 .
    > #d0,f
    > 0BF8:0000 E9 FD 00 E9 FA 00 E9 F7 00 00 00 00 00 00 00
    > 00 ................
    > #
    >
    > So.. the destination of the first jump is 00FDh in distance, the
    > second is 00FAh away, the third is 00F7h away.
    > E9 FD 00
    > E9 FA 00
    > E9 F7 00
    >
    > see?
    >
    > Steve
    >
    >> (The following listing was produced using
    >> RASM 1.4 under DR-DOS. By the way, anybody
    >> has a RASM manual? My "Programmer's Utility
    >> Guide" says that RASM has 25 error messages,
    >> but when I dump it, I find much more (even one
    >> in lowercase...) and the 8087 mnemonics,
    >> which are not mentioned anywhere... Also,
    >> the EXE file is 4 or 5 years older than the PUG.)
    >>
    >> Yours Sincerely,
    >> Mr Emmanuel Roche
    >>

    >
    >
    >


  4. Re: Intel 8086 opcodes

    Hello, Steve!

    > First, do you have this..?


    No. I only have the "Intel 8086 Family User's Guide" (which I find
    useless). I just found on the Internet a 1981 Intel manual which
    should help me. I should receive it in one week.

    > > When disassembling ASM-86 Version 1.1,
    > > I could not prevent myself from noticing that
    > > it was generating code different from RASM 1.4.

    >
    > I'm sorry I don't see what you mean. ASM86 outputs a binary form,
    > RASM a relocatable form for LINK86.


    ASM-86 (can) outputs an Intel 8086 hex file, RASM-86 an Intel OBJ
    file.

    By "code", I was meaning: the resulting CMD file (after GENCMDing it,
    or LINKing it). ASM-86 and RASM-86 (and PL/M-86) all don't produce the
    same "code". (And SID-86 has its own Assembler and Lister (like Good
    Old 8-bit SID), but let us not mix everything.)

    > > To study where was the difference, I wrote
    > > an I8086.A86 file...

    >
    > > Unfortunately, I have not been able to
    > > generate any of the 82 opcodes...

    >
    > > What am I missing?


    017A 03E8 add bp,ax ; 82
    ; 82 -- mod 001 r/m -- not used
    017C 13E8 adc bp,ax ; 82
    017E 1BE8 sbb bp,ax ; 82
    ; 82 -- mod 100 r/m -- not used
    0180 2BE8 sub bp,ax ; 82
    ; 82 -- mod 110 r/m -- not used
    0182 3BE8 cmp bp,ax ; 82

    You will note that none of the above lines start with an 82 opcodes.

    This is my question: I am able to generate all the other opcodes, but
    how do I generate the 82 opcodes?

    > Maybe I'm not answering your question, maybe I didn't understand your
    > question. It is a start.


    Yes. Thanks.

    > The source to ASM86 is available, I think it is in the DRIPAK.ZIP, but
    > most of it is PL/M source. The programmer uses the 'code macro'
    > method to construct the byte codes for the instructions.


    I should know: I have disassembled ASM-86 Version 1.1 (that is to say;
    precisely the one whose source code is available... Maybe it is a
    coincidence?) (By the way, this use of the "codemacro" concept means
    that ASM-86 is a table-driven assembler...)

    > You could also research the Netwide Assembler source code written in
    > C, but there is alot to wade through. But, using the the appendix and
    > sid, is easiest, poke in some bytes and let sid decode it,[list]. Or,
    > try some instructions to see how they assemble into byte strings...


    1) Since I am a CP/M fan, I could not care less about other assemblers
    running under other operating systems. What I want is to keep using CP/
    M Plus on an IBM Clown, so I need an 8086 assembler, and I need it to
    be the best possible (so, at the minimum, to generate all the Intel
    8086 opcodes...).

    2) SID-86 has a totally different way to assemble and list programs
    being debugged. So, let us not mix everything, and concentrate
    precisely on the Intel 8086 instruction set. (I hope that you know
    that Digital Research assemblers have a variant of 4 Intel 8086
    mnemonics?)

    > So.. the destination of the first jump is 00FDh in distance, the
    > second is 00FAh away, the third is 00F7h away.
    > E9 FD 00
    > E9 FA 00
    > E9 F7 00
    >
    > see?


    Yes. These are E9 opcodes, not 82 opcodes. QED.

    > > (The following listing was produced using
    > > RASM 1.4 under DR-DOS. By the way, anybody
    > > has a RASM manual? My "Programmer's Utility
    > > Guide" says that RASM has 25 error messages,
    > > but when I dump it, I find much more (even one
    > > in lowercase...) and the 8087 mnemonics,
    > > which are not mentioned anywhere... Also,
    > > the EXE file is 4 or 5 years older than the PUG.)


    To finish:

    1) My copy of the PUG says that RASM-86 has 25 error messages. I
    counted: RASM-86 Version 1.4 has 35...

    2) My copy of the PUG only mention 8086 mnemonics, a dump of the
    program shows that it understands8087 mnemonics. (At first sight,
    RASM-86 uses non-standard 8087 mnemonics. Or, some of them are non-
    standard.)

    So, if someone has a later guide or manual giving the exact list of
    the mnemonics recognized by RASM-86, he is welcomed...

    Yours Sincerely,
    Mr Emmanuel Roche



  5. Re: Intel 8086 opcodes

    On 2007-08-29, roche182@laposte.net wrote:
    > 017A 03E8 add bp,ax ; 82


    I don't understand why you think this should be an 82 opcode. As I
    read the various references on the net, I see an 82 opcode being
    more like ADD DS:[BX+SI],Imm8. And MS-DOS debug concurs:

    -u100
    0B70:0100 820000 ADD BYTE PTR [BX+SI],00

    I don't know the RASM syntax for this instruction, but I'm pretty
    certain it doesn't involve either BP or AX.
    --
    roger ivie
    rivie@ridgenet.net

  6. Re: Intel 8086 opcodes

    On Aug 29, 6:55 am, roche...@laposte.net wrote:
    > Hello, Steve!
    >
    > > First, do you have this..?

    >
    > No. I only have the "Intel 8086 Family User's Guide" (which I find
    > useless). I just found on the Internet a 1981 Intel manual which
    > should help me. I should receive it in one week.
    >

    Yes, perhaps you cannot use a .pdf file. It would be convenient to
    work off a common, commonly available, document.

    > > > To study where was the difference, I wrote
    > > > an I8086.A86 file...

    >
    > > > Unfortunately, I have not been able to
    > > > generate any of the 82 opcodes...

    >
    > > > What am I missing?

    >


    Point 3 is what Barry mentions.
    3) There is more than one avenue to the same destination.

    > 017A 03E8 add bp,ax ; 82
    > ; 82 -- mod 001 r/m -- not used
    > 017C 13E8 adc bp,ax ; 82
    > 017E 1BE8 sbb bp,ax ; 82
    > ; 82 -- mod 100 r/m -- not used
    > 0180 2BE8 sub bp,ax ; 82
    > ; 82 -- mod 110 r/m -- not used
    > 0182 3BE8 cmp bp,ax ; 82
    >
    > You will note that none of the above lines start with an 82 opcodes.
    >
    > This is my question: I am able to generate all the other opcodes, but
    > how do I generate the 82 opcodes?
    >

    A) Well, you definitely won't with those instructions, as Roger says,
    the instruction form is OP reg8|mem8,Immediate Value8. Plus, it is a
    5 bytes long interpretation.
    ex. ADD AX,9

    B) Still, there is the issue of the assembler itself, it may optimize
    the instruction to an alternate convenient form - you may not be able
    to generate the 5 byte instruction with the assembler except through
    the inline DB directive.

    >
    > > So.. the destination of the first jump is 00FDh in distance, the
    > > second is 00FAh away, the third is 00F7h away.
    > > E9 FD 00
    > > E9 FA 00
    > > E9 F7 00

    >
    > > see?

    >
    > Yes. These are E9 opcodes, not 82 opcodes. QED.
    >


    Very well, returning to SID...

    --------------------------------------------------
    *** Symbolic Instruction Debugger *** Release 3.2
    Copyright (c) 1983,1984,1985,1988,1990,1991
    Digital Research, Inc. All Rights Reserved
    --------------------------------------------------

    #f0,+1ff,0
    #a0
    0BF8:0000 add ax,5
    0BF8:0003 adc ax,6
    0BF8:0006 sbb ax,7
    0BF8:0009 cmp ax,8
    0BF8:000C .
    #d0,f
    0BF8:0000 05 05 00 15 06 00 1D 07 00 3D 08 00 00 00 00
    00 .........=......

    We see above that SID generates the short form of these instructions,
    no 82h.

    #a10
    0BF8:0010 add [100],9
    ambiguous operand
    0BF8:0010 add byte[100],9
    0BF8:0015 .
    #d10,1f
    0BF8:0010 80 06 00 01 09 00 00 00 00 00 00 00 00 00 00
    00 ................

    The above, less common instruction ADD mem,immed - is generated as the
    5 byte form, but still no 82H, but an equivalently interpreted form.

    But, will SID at least correctly decode the 82h form?
    #s20
    0BF8:0020 00 82
    0BF8:0021 00 06
    0BF8:0022 00 00
    0BF8:0023 00 01
    0BF8:0024 00 09
    0BF8:0025 00 .
    #l20,+5
    0BF8:0020 ADD BYTE [0100],09
    0BF8:0025 ADD [BX+SI],AL
    #

    QED.

    Steve

    > Yours Sincerely,
    > Mr Emmanuel Roche




  7. Re: Intel 8086 opcodes

    On Aug 29, 6:55 am, roche...@laposte.net wrote:
    > Hello, Steve!


    > > You could also research the Netwide Assembler source code written in
    > > C, but there is alot to wade through. But, using the the appendix and
    > > sid, is easiest, poke in some bytes and let sid decode it,[list]. Or,
    > > try some instructions to see how they assemble into byte strings...

    >
    > 1) Since I am a CP/M fan, I could not care less about other assemblers
    > running under other operating systems. What I want is to keep using CP/
    > M Plus on an IBM Clown, so I need an 8086 assembler, and I need it to
    > be the best possible (so, at the minimum, to generate all the Intel
    > 8086 opcodes...).
    >

    I have no criticism of what you say, just an observation. Gary cross
    developed CP/M itself.

    'to generate all the Intel 8086 opcodes', including the 32bit forms?
    I've done alittle with code macro definitions to try some of this,
    which works in pricinple, but it is a big effort, and I'm not sure the
    internal code macro symbol table is big enough to hold the entire
    effort. That is why I turned my attention to NASM.

    > 2) SID-86 has a totally different way to assemble and list programs
    > being debugged. So, let us not mix everything, and concentrate
    > precisely on the Intel 8086 instruction set. (I hope that you know
    > that Digital Research assemblers have a variant of 4 Intel 8086
    > mnemonics?)
    >

    Do you have a table of these? I sense another Roche document is
    needed!

    It is funny that the SID disassembly syntax is very close to NASM's
    syntax, closer to NASM than to ASM86!

    But, after all, we are talking about variance in Syntax, not unlike
    that found in various Basics, no?

    Steve

    p.s. in my previous example I used ex. ADD AX,9 in following your
    listing, but as I noted the 82h opcode is for a form of ADD AL,9 that
    is, OP reg8,immed8 and I wasn't clear enough about that.


  8. Re: Intel 8086 opcodes

    Hello, Steve and Jonathan!

    With both of you, I am convinced that we will manage to understand the
    8086 opcodes.


    > I have no criticism of what you say, just an observation. Gary cross
    > developed CP/M itself.


    Yes, using IBM S/360 and DECsystem-10 mainframes. Me, I am using one
    IBM Clown running at 400-MHz (100 times faster than my Beloved Epson
    QX-10) as my "mainframe". My main word-processing machine is a
    portable running at 6-MHz. I save the files on a 3.5" floppy, then
    either publish them here, or store them on the hard disk of my main
    machine, running under DR-DOS.

    > 'to generate all the Intel 8086 opcodes', including the 32bit forms?
    > I've done alittle with code macro definitions to try some of this,
    > which works in pricinple, but it is a big effort, and I'm not sure the
    > internal code macro symbol table is big enough to hold the entire
    > effort. That is why I turned my attention to NASM.


    There are about 290 tables to define the 8086 opcodes of ASM-86
    Version 1.1, since a table is required for all the forms of the
    mnemonics... (17 for "MOV"!) But this is the only way to get a table-
    driven assembler. And it works. (For your information, there is 321
    procedures in the assembler, so that means that RASM-86 has more
    tables defining the opcodes than procedures to produce them! As you
    may remember, I have disassembled, ASM Version 2, MAC Version 2, SID
    Version 3, and ZSID Version 2.5. I am realizing that the 8086 is even
    worse than the Z-80, with its 820 opcodes... Sigh! All that just to
    keep using CP/M Plus on IBM Clowns... Too bad Zilog never managed to
    produce faster Z-80-compatible microprocessors. Now, the only
    solution, to keep using CP/M Plus, is to run it on an IBM Clown, so to
    manage its awful CPU.)

    > > (...) (I hope that you know
    > > that Digital Research assemblers have a variant of 4 Intel 8086
    > > mnemonics?)

    >
    > Do you have a table of these? I sense another Roche document is
    > needed!


    Are you joking, Steve? It is in all my copies of ASM-86 and RASM-86
    guides: RETF, CALLF, CALLS, and JMPS. This way, no "short" word is
    needed, thus reducing a little the verbosity of the instruction set.

    > It is funny that the SID disassembly syntax is very close to NASM's
    > syntax, closer to NASM than to ASM86!


    As my I8086.A86 program shows, there are several opcodes that are
    produced by different mnemonics. This is the first time that I see a
    CPU with this horror. That means that the debugger can only use of
    these forms, and that, when debugging, you will NEVER see some
    mnemonics that are in your source code! This is totally silly, crazy,
    etc. The Assemble portion of SID-86 is probably the shortest 8086
    assembler possible. But I have not yet disassembled it: one step at a
    time.

    Last week, jokingly, I wrote to one of my correspondent that I had
    nothing to read... Yesterday, I received 4 messages needing long
    technical replies... Last night, I only managed to write one answer...
    This night, I will work on this thread, so I can publish my answer
    tomorrow, the last day of this week where I will be able to reach the
    Internet.

    Yours Sincerely,
    Mr Emmanuel Roche



  9. Re: Intel 8086 opcodes


    wrote in message
    news:1188557697.144281.184940@x35g2000prf.googlegr oups.com...
    Too bad Zilog never managed to
    > produce faster Z-80-compatible microprocessors. Now, the only
    > solution, to keep using CP/M Plus, is to run it on an IBM Clown, so to
    > manage its awful CPU.)


    50 MHz isn't fast enough for you? It runs rings around even the first
    Pentium
    @ 60 MHz. (for operations that don't need the math coprocessor!).

    Tom Lake



  10. Re: Intel 8086 opcodes

    roche182@laposte.net wrote:
    (snip)

    > As my I8086.A86 program shows, there are several opcodes that are
    > produced by different mnemonics. This is the first time that I see a
    > CPU with this horror. That means that the debugger can only use of
    > these forms, and that, when debugging, you will NEVER see some
    > mnemonics that are in your source code!


    I don't think it is that unusual, though maybe worse here.

    In many cases NOP is another machine instruction that doesn't
    actually do anything. A move of a register to itself, or
    a conditional branch with the condition turned off.
    I believe the 8080 NOP is MOV A,A but someone here will tell
    me if it isn't.

    S/360 has the extended mnemonic branch instruction, instead
    of having to remember the condition code bits, NOP and
    NOPR being two of those.

    -- glen


  11. Re: Intel 8086 opcodes

    >> As my I8086.A86 program shows, there are several opcodes that are
    >> produced by different mnemonics. This is the first time that I see a
    >> CPU with this horror. That means that the debugger can only use of
    >> these forms, and that, when debugging, you will NEVER see some
    >> mnemonics that are in your source code!


    >I don't think it is that unusual, though maybe worse here.


    It's not uncommon - some simple examples are:

    JE JZ / BE BZ Jump/Branch on Zero flag seg
    JNE JNZ / BNE BNZ Jump/Brancj on Zero flag NOT set
    JB JC / BLO BCS Jump/Branch on Carry flag set
    JAEJNC / BHS BNC Jump/Branch on Carry flag NOT set
    ASR LSR Arithemetic/Logical shift right

    You only ever see one or the other in a larticular debugger.
    There are more - the 8086 takes it one step further and provides
    different encodings which mean the same thing.

    >In many cases NOP is another machine instruction that doesn't
    >actually do anything. A move of a register to itself, or
    >a conditional branch with the condition turned off.
    >I believe the 8080 NOP is MOV A,A but someone here will tell
    >me if it isn't.


    The 8080 has an opcode (00) reserved for NOP - MOV A,A
    is (iirc) 7F - but essentially the same thing. Waste a couple of
    cycles, move no data, and set no flags. You can use any of
    the general purpose registers (B,B - C,C etc.) with the same
    effect - except for M,M which is not a valid encoding - if the
    assembler accepts it it results in a HLT (76) instruction.

    >S/360 has the extended mnemonic branch instruction, instead
    >of having to remember the condition code bits, NOP and
    >NOPR being two of those.


    Yes, exactly like the examples above (taken from Intel and
    Motorola micros). BCS means branch on carry set - Carry
    is set after a compare if unsigned A < B, therefore BLO
    (Branch on LOwer) also encodes tothe same opcode (as
    BCS)

    Dave

    --
    dave06a@ Low-cost firmware development tools: www.dunfield.com
    dunfield. Classic computer collection: www.classiccmp.org/dunfield
    com Some stuff I have for sale: www.dunfield.com/sale


  12. Re: Intel 8086 opcodes

    Dave Dunfield wrote:

    (snip)

    > The 8080 has an opcode (00) reserved for NOP


    Now I remember. It used to be that ERPOMs would
    clear to 00 (in PMOS days), but NMOS ones clear to
    FF. (I don't know why they couldn't put an inverter
    in to change that.)

    00 was considered an advantage for the 8080, one could
    put in NOPs and later change them.

    -- glen


  13. Re: Intel 8086 opcodes

    Hello, Glen!

    > 00 was considered an advantage for the 8080, one could
    > put in NOPs and later change them.


    One of my (big) surprise, when moving to the 8086, was that NOP is now
    90h...

    The problem being that GENCMD, LINK, etc, all fill unused space with
    00h, with is now a valid 8086 opcode!

    (ASM-86 fills erroneous fields with 90hs.)

    I simply cannot understand why the newbies Intel electronics engineers
    chose 90h, rather than continue to use 00h.

    Yours Sincerely,
    Mr Emmanuel Roche



  14. Re: Intel 8086 opcodes

    Re-hello, Steve and Jonathan!

    > This night, I will work on this thread, so I can publish my answer
    > tomorrow, the last day of this week where I will be able to reach the
    > Internet.


    I am really sorry, but this stuff is so technically difficult that I
    did not manage to produce anything publishable on the comp.os.cpm
    Newsgroup last night. I worked until my eyes were closing, then
    decided to go to bed.

    Among other things, I noted that all the versions of SID-86 for CP/
    M-86 that I have recognized the byte pattern proposed by Steve. I also
    found that 04 12 and 82 C0 12 both produce ADD AL,12h... I also had
    the idea to search for any "82" in my source code: there is none. But
    the problem is that some opcodes are produced as bytes, and some are
    combined to produce a byte... Anyway, it is a difficult subject, and I
    think that I will spend the week-end working on it...

    One reason is that, the afternoon, I spent 3 hours with the manager of
    the cybercafe from where I am sending this, trying to make Windows 98
    SE recognize a WiFi PCMCIA card and the CD-ROM drive of a second-hand
    portable that I bought (my only computer with a CD-ROM). After 3 hours
    of work, we decided to quit on failure. The manager had the idea of
    using one of his CDs, booting a Linux distribution: it worked (very
    slowly), and recognized the WiFi card! So, why is W98SE not
    recognizing both? We have no idea. Is anybody out there who has a
    unused copy of W98SE (the CD-ROM and its manual with the password)? We
    think that the only solution is to re-install Windows (that's the way
    99% of microcomputer shops now do) but, since it is a second-hand
    portable, I don't have any original W98SE CD-ROM or booklet.

    Yours Sincerely,
    Mr Emmanuel Roche



  15. Re: Intel 8086 opcodes

    82OPCODE.WS4 "How to produce 82 opcodes with ASM-86"
    ------------

    (This text is dedicated to Robert ("Bob") Silberstein, the
    author (in 1981) of ASM-86, the CP/M 8086 assembler of Digital
    Research.)

    After disassembling ASM-86 Version 1.1 (whose PL/M source code
    has been released to the public domain by Caldera after buying
    DR-DOS), I finally had the idea of testing it.

    Before, when we used 8-bit CP/M 2.2, the opcodes of the 8080/Z-
    80 were so easy that, at a glance, we knew what they were
    standing for.

    This is no longer, unfortunately, the case with the 8086 CPU of
    the IBM Clown. A proof of that sad state is ASM-86, which is 5
    TIMES bigger than ASM 2.0!

    So, to be sure not to make an error, I took my well worn copy of
    "The 8086 Primer", the book written by one of the four
    electronics engineers who designed the 8086 CPU for Intel.

    Appendix B is titled: "8086 Opcode Space", and contains a 16x16
    matrix, with a "Secondary Opcode Space" table giving the
    mnemonics using 2 bytes of opcode. (The 8086 CPU has 32 2-byte
    opcodes: the rest are 1-byte opcodes.)

    With that, I produced a I8086.A86 file that produced all the
    opcodes mentioned, EXCEPT the 82 series. The "Secondary Opcode
    Space" table was saying that there are four ADD instructions,
    starting with a 80, 81, 82, and 83 opcodes. I had no problem
    with the other three opcodes but, no matter what I tried, I did
    not manage to produce any 82 opcode for the ADD instruction.

    So, back to reading yet-another-time the book. This book is a
    pain to use, because everything is in binary...

    Ho, by the way,
    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

    Ok. First thing to notice: they were using 6 bits to code their
    one-byte long opcodes, so

    80h = 100000 00
    81h = 100000 01
    82h = 100000 10
    83h = 100000 11

    The first and third forms of ADD start with a 0 bit, so are not
    what we are searching for. The second, however, starts with a 1
    and follows with five 0 bits, so this is the one we are
    investigating.

    This figure means, as far as I understand, that this instruction
    produces either 3 or 4 bytes of opcode ("data if S,W = 01"). We
    have just seen that "01" is the case for 81h. Logically, the 82
    opcode should be followed by a byte (since 81 is followed by a
    word).

    Searching for more clues, I found figure 2.24.

    Figure 2.24 shows an example of such an instruction. In this
    example, the value 0000 0000 0000 1111 is added to the contents
    of a word in memory, and the result placed back into the memory
    word. The memory word is in the data segment at the offset
    contained in DI. Note that one byte is eliminated by having the
    S field.

    opcode S W MOD opcode R/M data
    +-------------+---+---+ +-----+-------+-------+ +-----------------+
    | 1 0 0 0 0 0 | 1 | 1 | | 0 0 | 0 0 0 | 1 1 1 | | 0 0 0 0 1 1 1 1 |
    +-------------+-+-+-+-+ +-+---+-------+-------+ +-----------------+
    ADD | | | ADD DI
    | | +--> memory
    | +--> word
    +--> sign extend

    Figure 2.24 Example of immediate-operand instruction containing an S
    field


    Argh! This time, it is a 83 opcode...

    But, for 82, since S=1, W is false (0), hence it is a byte. Qed!

    It is also interesting to note the "opcode = 000 = ADD" comment
    in the mod/rm byte... This could be the key to understand the
    "Secondary Opcode Space".

    Ok. This is all I managed to find in the book. Back to the PL/M
    code.

    It shows a "code-macro table" with mnemonics in alphabetic
    order. However, when I disassembled ASM-86, I found that a lot
    (not all) of mnemonics were spread all over the code-macro
    table, instead of following the PL/M program. So, to help you, I
    am re-arranging the code of my A86 file.

    add1 dw nil ; ADD dst:Eb,srcb
    db 2
    db specE,modB
    db specD,modB
    db msegfix,dst
    db mdbn,80h
    db mmodrm1,0,dst
    db mdbf,src
    db mendm

    add2 dw add1 ; ADD dst:Ew,srcb
    db 2
    db specE,modW
    db specD,modB
    db msegfix,dst
    db mdbn,81h
    db mmodrm1,0,dst
    db mdwf,src
    db mendm

    add3 dw add2 ; ADD dst:Ew,srcsb
    db 2
    db specE,modW
    db specD,modSB
    db msegfix,dst
    db mdbn,83h
    db mmodrm1,0,dst
    db mdbf,src
    db mendm

    add4 dw add3 ; ADD dst:Ew,srcw
    db 2
    db specE,modW
    db specD,modW
    db msegfix,dst
    db mdbn,81h
    db mmodrm1,0,dst
    db mdwf,src
    db mendm

    add5 dw add4 ; ADD dst:Ab,srcb
    db 2
    db specA,modB
    db specD,modB
    db mdbn,04h
    db mdbf,src
    db mendm

    add6 dw add5 ; ADD dst:Aw,srcb
    db 2
    db specA,modW
    db specD,modB
    db mdbn,05h
    db mdwf,src
    db mendm

    add7 dw add6 ; ADD dst:Aw,srcw
    db 2
    db specA,modW
    db specD,modW
    db mdbn,05h
    db mdwf,src
    db mendm

    add8 dw add7 ; ADD dst:Eb,src:Rb
    db 2
    db specE,modB
    db specR,modB
    db msegfix,dst
    db mdbn,00h
    db mmodrm2,src,dst
    db mendm

    add9 dw add8 ; ADD dst:Ew,src:Rw
    db 2
    db specE,modW
    db specR,modW
    db msegfix,dst
    db mdbn,01h
    db mmodrm2,src,dst
    db mendm

    add10 dw add9 ; ADD dst:Rb,src:Eb
    db 2
    db specR,modB
    db specE,modB
    db msegfix,src
    db mdbn,02h
    db mmodrm2,dst,src
    db mendm

    add11 dw add10 ; ADD dst:Rw,src:Ew
    db 2
    db specR,modW
    db specE,modW
    db msegfix,src
    db mdbn,03h
    db mmodrm2,dst,src
    db mendm

    Gasp! What's that?

    They are code macros. That is to say: when Silberstein (or
    Digital Research) decided to write a 8086 assembler to port CP/M
    on the 8086 CPU, they noticed that NONE of the 6X opcodes were
    documented by Intel... That is to say: Intel was planing to
    introduce other CPUs, with opcodes to be added to the ones of
    the 8086. So, how to write an assembler, if you don't know at
    the start what will be the final instruction set?

    Apparently, they had some technical information from Intel, and
    could design a set of pseudo-instructions able to generate
    appropriate opcodes. The only known example is the 8087.LIB
    file, enabling ASM-86 Version 1.0 and 1.1 to generate 8087
    opcodes.

    Technically, we notice that each code macro has a comment... So,
    that means that this comment was enough for the original author
    to understand what it was meaning... So, we'd better be as
    intelligent as him!

    ADD dst:Eb,srcb
    ADD dst:Ew,srcb
    ADD dst:Ew,srcsb
    ADD dst:Ew,srcw
    ADD dst:Ab,srcb
    ADD dst:Aw,srcb
    ADD dst:Aw,srcw
    ADD dst:Eb,src:Rb
    ADD dst:Ew,src:Rw
    ADD dst:Rb,src:Eb
    ADD dst:Rw,src:Ew

    Obviously, "dst:" means "destination", and "src:" means
    "source".

    Now, we see in upper case: A, D, E, and R, and in lower case: b,
    sb, and w.

    According to my disassembly,
    A = Accumulator (AX or AL)
    D = Data (number used as immediate data)
    E = Effective address (either memory or register)
    R = Register only

    b = Byte
    sb = Signed Byte (-128, +127)
    w = Word

    That's all! So, where is the bug?

    Ok. Time to have a look to the I8086.LST file. (By the way,
    anybody has an idea what "R" means? It is not in the PUG.)

    0122 8006111112 R add label_b,12h ; 80

    014A 810622225634 R add label_w,3456h ; 81

    017A 03E8 add bp,ax ; 82

    0184 83C512 add bp,12h ; 83

    So, we see that 80 adds a byte at an address, 82 adds a word at
    an address. It is curious that both 82 and 83 adds a byte, but
    so be it.

    Upon re-reading the code macros, we find that:

    ADD dst:Eb,srcb add1 = 80
    ADD dst:Ew,srcb add2 = 81
    ADD dst:Ew,srcsb add3 = 83
    ADD dst:Ew,srcw add4 = 81
    ADD dst:Ab,srcb add5 =
    ADD dst:Aw,srcb add6 =
    ADD dst:Aw,srcw add7 =
    ADD dst:Eb,src:Rb add8 =
    ADD dst:Ew,src:Rw add9 =
    ADD dst:Rb,src:Eb add10 =
    ADD dst:Rw,src:Ew add11 =

    The other code macros are, obviously, the other ADD opcodes
    starting with a 0 bit. But 2 questions are raised:

    1) Why is there two 81 opcodes?
    2) Why is the 83 opcode the only one involved with "Signed Byte"
    (-127, +128)?

    1) Upon closer examination,
    ADD dst:Ew,srcb add2 = 81
    ADD dst:Ew,srcw add4 = 81
    it is obvious that the difference is that ADD2 uses a byte as
    its source, while ADD4 uses a word.

    2) Now for the 83 opcode.
    ADD dst:Ew,srcsb add3 = 83
    We have seen that its explanation (Figure 2.24) was precisely
    saying that, due to the S field (sign extent), it was indeed
    designed for signed byte.

    Now, how to check this?

    I tried to assemble a file with various byte values:
    0006 83C57E add bp,126
    0009 83C57F add bp,127
    000C 81C58000 add bp,128
    0010 81C58100 add bp,129
    0014 83C500 add bp,0
    0017 83C5FF add bp,-1
    001A 83C5FE add bp,-2
    001D 83C581 add bp,-127
    0020 83C580 add bp,-128
    0023 81C57FFF add bp,-129
    0027 81C57EFF add bp,-130
    but, as can be seen, ADD3 does not complain when values outside
    the signed byte domain are used... (Or, more exactly, ASM-86
    then uses 81 opcodes, without outputting any error message.)
    (But how would an assembler know if a byte variable is signed or
    not?)

    Haha! And if tried EQUated variables? (Rather than immediate
    values.)

    Argh! Despite being now able to check the values EQUated, ASM-86
    still does not complain, and outputs the same stuff. I simply
    don't know why there is this "signed byte" distinction, since
    ASM-86 do not seem to take care of it.

    So, we have a problem. Or, Silberstein coded the code macro of
    ADD3 thinking that it was an unsigned byte. This way, the ADD3
    code macro would be, in fact, the code macro for the 82 opcode.
    But how to know?

    Since I have my A86 file available, I searched for "signed
    bytes". They don't exist for "destination", only for "source".

    Maybe you remember that the "Secondary Opcode Space" says that
    there are 8 opcodes starting with 80-83? Well, I only found 5
    comments with "sb": those of ADC, ADD, CMP, SBB, and SUB.
    Missing are: AND, OR, and XOR.

    I then had a look to the code macros of those 3 mnemonnics: all
    have 80 and 81 (twice), but none has a 82 or 83 opcode... That
    means that 8 code macros (at the minimum) will have to be added
    to the assembler...

    But the biggest problem remains: what is the difference between
    82 and 83 opcodes, since both are dealing with bytes?

    Since it would be curious that Intel designed a CPU with
    redundant opcodes, and since, over and over, all the
    instructions are repeated for byte or word, for integer and
    signed integer, the only reasonable solution that I can see is
    that the 82 opcode was designed for unsigned bytes, commonly
    called "bytes"...

    So, its comment would be:
    ADD dst:Ew,srcb add82 = 82
    and, since the first three instructions are involved with bytes
    before taking care of words,
    ADD dst:Eb,srcb add1 = 80
    ADD dst:Ew,srcb add2 = 81
    ADD dst:Ew,srcsb add3 = 83
    ADD dst:Ew,srcw add4 = 81
    that means that 82 should be between ADD2 and ADD3 (82 between
    81 and 83!).

    By the way, the 3 logical opcodes only have 80, 81, 81: this
    could mean that they all miss 82 and 83 opcodes... (Isn't
    assembly language wonderfully logical?)

    As I wrote in the comp.os.cpm Newsgroup, I am waiting to receive
    an 1981 Intel book detailing the opcodes of the 8086 CPU.

    By the way, speaking of technical documentation, all the
    documentations of ASM-86 I have read mention: "For a more
    detailed description of each instruction, see Intel's "MCS-86
    Assembly Language Reference Manual". For descriptions of the
    instruction bit patterns and operations, see Intel's "MCS-86
    User's Manual". I have been trying to find these, especially the
    latter, since it was it that led the programmer to include 5
    mentions of a "signed byte" operand in the code macros, but
    without any success... Google only has a handful of MCS-86
    links. They seem to be totally lost. (Intel if famous for losing
    its documentation, like InSite...)

    If someone has any idea or comment meanwhile, he is welcome!

    You may have noticed that I spend my time asking: "Why?" Here is
    another question that I simply cannot prevent from haunting me:
    we have seen that there are 4 secondary opcodes: 80, 81, 82, and
    83.
    0122 8006111112 R add label_b,12h ; 80
    014A 810622225634 R add label_w,3456h ; 81
    017A 03E8 add bp,ax ; 82
    0184 83C512 add bp,12h ; 83
    80 adds a byte, 81 adds a word. Since everything in the 8086
    instruction set is so systematically regular (byte then word,
    integer then signed integer), I agree that 82 should immediately
    adds a byte to the accumulator but, why is 83 not adding a word,
    since its W field is 1 (83h = 100000 11, if you remember: that
    is to say: extend the sign (useless if it is a word...) and word
    value...)...

    Isn't the 8086 CPU instruction set wonderful? Still provoking
    discussions 30 years after its introduction! (And notice how
    badly documented it is, 30 years later, since nobody in this
    world-wide Newsgroup has been able to say anything about the 82
    series of opcodes! Officially, there are HUNDREDS of millions
    IBM Clowns in the world, and nobody has the slightest idea what
    its instruction set is... Isn't it wonderful? We are, truly,
    living in a fantasy land... Hollywood has won! Harder will be
    the fall.)


    Yours Sincerely,
    Mr Emmanuel Roche



  16. Re: Intel 8086 opcodes

    On Sep 3, 2:54 am, roche...@laposte.net wrote:
    > 82OPCODE.WS4 "How to produce 82 opcodes with ASM-86"
    > ------------


    > So, its comment would be:
    > ADD dst:Ew,srcb add82 = 82

    According to the Appendix A: Machine Instruction Decoding Guide, the
    form of 82h is:
    OP reg8|mem8,Immed8.
    dst:Ew should be dst:Eb for 82h. The destination is a byte register,
    not word register.

    This is starting to be alittle more clearer, if the destination is a
    register, in this case the byte sized register like AL, then the byte
    string generated is 3 byte form, the register is encoded in the reg
    field of the second byte, the immed value is the third byte. If the
    destination is an EA, effective address, then the 5 byte string is
    formed with byte 3 := low_displacement, byte 4 := high_displacement,
    byte 5 := Immed byte value. The displacement is a word-sized offset
    to byte data location.

    Steve
    >
    > Yours Sincerely,
    > Mr Emmanuel Roche




  17. RISC vs CISC Re: Intel 8086 opcodes

    In article <1188809693.591491.159770@d55g2000hsg.googlegroups. com>, roche182@laposte.net wrote:
    > 82OPCODE.WS4 "How to produce 82 opcodes with ASM-86"


    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? 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.

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

    On Mon, 3 Sep 2007 15:01:40 GMT, B'ichela
    wrote:

    >In article <1188809693.591491.159770@d55g2000hsg.googlegroups. com>, roche182@laposte.net wrote:
    >> 82OPCODE.WS4 "How to produce 82 opcodes with ASM-86"

    >
    >Just a quick question. of the Major processors used in Home PCs from
    >the 4004,



    4004 never made it as PC cpu way to small (4bit data path).

    8008 start of teh revolution at 8bits but still limited. NOT RISC.

    8080,8086 (I doubt this one) NOT RISC by any stretch.


    , 6502, 6510 CLOSE, May even qualify.

    6809 NOT close , very CISC.
    Same for 8085, Z80 Ti9900 and a much more.

    >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


    Also usualy implies reduced instruction set cycle count too.
    If it were only instructions 1802 would qualify but the 8/16/24 clock
    cycles to execute instructions does not fit.

    >Risc chip? 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.


    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.

    However ponder PDP-8, small instruction set, the real machines
    (not the CMOS equivilents) executed instructions in very few cycles.

    None of the machines that run CP/M or any varient is RISC.

    Allison

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

    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!

    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.



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

    --
    ┌── 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

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

    --{ B'ichela a plop ceci: }--

    > Risc chip? 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.


    If my memory wasn't corrupted by cosmic rays, first ARM chips
    have only 27 instructions...

    --
    "Le mdecin, depuis qu'il a l'ordinateur, quand il te parle, il te
    regarde plus : il regarde son ordinateur avec une tronche, mon pauvre,
    on dirait qu'il a bouff un ver."

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