Machine command is answering 3 question to processor.
1. What to do?
2. With what to do?
3. How to do?
3rd question is optional.
To answer those questions command may have several logical blocks.
Before enumerating those blocks we'll see some examples.
And before that examples let's make special programme which
will serve us as white sheet of paper.
Of course we may do it in any program loaded into debugger but better
do fool code app.
1. We'll do it small so it will be loaded faster in OllyDbg.
2. We'll fill it with 1byte mnemonic so we can that mnemonic
on unused space of the test prog and treat it as if it white
part of paper sheet.
3. If we use the same program for our tests we can create
either batfile to load it into OllyDbg. Or specify the name of
our app as command line inside shortcut (lnk file) to OllyDbg.
It gives us opportunity to load OllyDbg with testing white sheet app
inside it by dblclick.
Last loaded fileS in OllyDbg you may find in File menu at the bottom.
And last loaded file you load just by pressing ctrl+F2.

so here is "white sheet app" source.
rept 256
call ExitProcess
end start
It will insert 256 nops inside.
Or as you already now 256 90h bytes before call ExitProcess code.
So maybe we code it partly in HEX then? :)
rept 256
db 90h
call ExitProcess
end start
or maybe we chek if all this
db 90h
xchg eax,eax
are the same thing?
Let's retype and recompile it with
rept 20
rept 118
xchg eax,eax
rept 118
db 90h
call ExitProcess

When you load it into debugger you'll this all the same 90 nop

call ExitProcess.
Now I suggest that you are very advance Win32 user, and can add to your
start menu item with command OllyDbg.exe
and give it shortcut key for example ctrl-shift-t.
So you can load your test app in debugger with one keystroke.

Introduction to opcode logical blocks
There are 6 logical blocks that might be used in opcode.
Important thing is not only names and meaning of them,
but also the order of them.
Here they are:
3.byte mod r/m
4.byte sib
5.offset in command
6.imm. operand.
Not necessarily all of them are used.
But one block is used always
it is block2 -> CODE.
Some commands used just this one block.

Type in test prog opcodes (press enter after each byte and look to
what mnemonic appeared)
Remember? Ctrl-e to insert raw opcode.
90 ;you already know what you'll see don't you :)
All this opcodes has the only field - CODE.
We already know opcode for lodsb - ACh
let's see if we can add additional block to it to extend
it usage.
Type in raw opcode F3 before AC
in other words type (after ctrl-e)
You can see: rep lodsb
We can specify block format for
AC as

F3AC as

F3 is prefix block.F3 is value of Rep prefix.
It is used the same way with movsb, stosb etc.
Now type those mnemonics of commands that you know can
be used with rep before them.
Look up their opcodes.
Now type in raw hex (ctrl-e)
each of these mnemonics opcode with leading F3 byte.
See results of recognized mnemonics.
So first thing to remember:
Command may be constructed using some of six logical
blocks. Not all are necessarily used, but one block
is always present - CODE(block#2)

Now we'll make example of what real men see in opcode,
continuing looking through examples of opcode
in blocks.
To see what power can we get by knowing it.
Lets insert all 6 mnemonics for work with BCD numbers.
Type mnemonics in debugger:
When first time those commands were represented by Intel,
documentation said that all off them are 1 block commands.
That means that they are in format
Actually the real format of the last two was not documented.
Let us see if we can figure out this format and what we additionally
can discover looking in opcode:

27 DAA
37 AAA

Is there something different in AAM and AAD from the others?
Don't look for a while below.Try to think yourself about the difference.

1. These two are two bytes long while other 4 is 1 byte.
2. Second byte of both commands is 0A.
If you remember of description of the commands
AAM - divide al by 10
place quotient in AH
place reminder in AL
AAD - AL = AH*10+AL
So both commands works with 10.
And last byte of them opcode is 10 (0Ah)
Might be it is 0Ah not accidentally?
Maybe it is an operand?
And format of the commands is not
D40A for AAM
D50A for AAD
May be it is
And imm8 may be any value?
Try to check it.
Type for example:
mov al,8
then as OPCODE
D407 ;do the same as D40A does but divide by 7 not ten
if we are right then after running this opcode we
will have 01 in AH(quantient) and 01 in AL(reminder)
so type it and run step by step using F8, looking what happens in registers.
Now try the experiment with second byte of D5:imm8 opcode.
Try type and run example with imm8 different from 0Ah and see what
will happen.

So now we not only saw another format example
 (block2 and block6) 

we also saw type of opcode that exists but don't have mnemonic for it.
I must say that Oleh (Author of OllyDbg) use his notation for it:
he allows (as you could see after typing D407) to use immediate operand to
those two opcodes with AAM and AAD mnemonics.

Understanding rules of opcode format helped low level coders recover those
undocumented opcodes and document them. Another advantage of opcode

We'll study each block of opcode in detail later.
Now we need to see some basic rules.
The second thing to remember is that though not necessary all blocks
are present in particular opcode the order of blocks never changed.
Some blocks may be missing but block with low order number never occurs
after block with higher number.
There is always
 in command and never 
 in one

Type OPCODE 0110 press enter
then type 1001 press enter
As you see we've to different commands.

Next time we'll discuss how processor recognise start and end of opcode,
and will see how 2+2 maybe equal 3 ;)
Posted on 2002-11-16 04:14:41 by The Svin
nice tutor again.
Posted on 2002-11-16 13:11:38 by nyook
BTW, F2/F3 prefix works very well against indiscretions ;)
Posted on 2002-11-20 22:33:36 by Axial