News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Opcode forms

Started by entry1wound, October 01, 2010, 08:18:33 PM

Previous topic - Next topic

entry1wound

Hello,

I just recently started using MASM, and I have what may seem like a very nit-picky question.


As an example, we'll take the ADD instruction:

I'll write ADD eax, 02h, and it will do exactly what I want it to do (of course).  But, there is another form of the instruction that is not only faster, but smaller, and it's the implied accumulator form (al, ax, eax).  The hex opcode for the add rm, imm is 80 /r, but for this implied instruction it is simply 00, 01, 02 (for al, ax, eax, etc.)

Using that form I would logically write:

ADD 02h

But this produces an assembly error.

Is there a reason this happens or is this my misunderstanding?  Thanks in advance to anyone who might help.

RuiLoureiro

Quote from: entry1wound on October 01, 2010, 08:18:33 PM
Hello,

As an example, we'll take the ADD instruction:

I'll write ADD eax, 02h, and it will do exactly what I want it to do (of course). 
Using that form I would logically write:
ADD 02h

But this produces an assembly error.

Hello,
           The assembler understand this: «add    eax, 02h»
            Does your the assembler  understand this: «add 2h»  ???
            This seems to be the question ! Mine doest understand
RuiLoureiro             

clive

Quote from: entry1wound
The hex opcode for the add rm, imm is 80 /r, but for this implied instruction it is simply 00, 01, 02 (for al, ax, eax, etc.)

Is there a reason this happens or is this my misunderstanding?

Your misunderstanding. The assembler wants to know a register or memory address (R/M), and the immediate value.

The 80x86 knows AL,AX in 16-bit mode, and AL,EAX in 32-bit mode. To use EAX in 16-bit mode, or AX in 32-bit mode, requires an instruction override prefix.

The 80 opcode is for the add reg/mem8, imm8 form

In 16-bit

1368:0100 0402          ADD     AL,02
1368:0102 050200        ADD     AX,0002
1368:0105 80C302        ADD     BL,02
1368:0108 80C702        ADD     BH,02
1368:010B 80C102        ADD     CL,02
1368:010E 80C502        ADD     CH,02
1368:0111 80C202        ADD     DL,02
1368:0114 80C602        ADD     DH,02


ADD AX,2 could also code as 83 C0 02, but that isn't any more efficient.

In 32-bit you can save a few bytes, but it won't run faster

00000000  83 C0 01                add     eax,1
00000003  83 C0 04                add     eax,4
00000006  05 00000001                add     eax,dword ptr 1
0000000B  05 00000004                add     eax,dword ptr 4


The 8086 is not intrinsically an accumulator machine, although it has some of that lineage. The instructions are viewed by the assembler in a more orthogonal way, and in a manner that permits the syntax to clearly define the action desired.
It could be a random act of randomness. Those happen a lot as well.

dioxin

entry1wound,
There is no such implied instruction.
The byte 00 is specified in the Intel Manual as:
Quote00 /r        ADD r/m8,r8        Add r8 to r/m8

The /r shows that a second byte is required (the Mod/RM byte) to specify what is to be added to what and that byte will specify the target register.

Download a copy of the Intel Pentium manuals and check out Volume 2:
http://www.intel.com/design/pentiumii/manuals/243191.htm
Look at the chapter on Instruction format.


It's a good reference to have handy when you're programming in asm.

Paul.

dioxin

entry1wound,
I think I see what you mean now.
The opcode is 04 or 05 (not 00, 01, 02).

MASM appears to compile the shortest opcode that does the job.
If you have add eax,2 then the 2 possible forms would be
05 02 00 00 00  'add the 32 bit immediate value 00000002 to eax
or
83 C0 02        'add the immediate byte 02 to eax


The second is shorter.

If you change the immediate value to something more than a byte then the other form becomes shorter so that's the one used:
For add eax,12345678h the 2 possible forms would be
05 78 56 34 12    'add the immediate value 12345678 to eax
or
81 C0 78 56 34 12 'same as above but 1 byte longer

entry1wound

I did some digging and discovered this by myself.  Thank you for the explanation, I thoroughly appreciate when people give reasonable responses.  In any case, it was just a nitpick  :toothy, no it was not a matter of importance.  Good to know.   Thank you guys.