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