Since nobody yet responded on modr/m decoder
optimization, I offer a much more simple task.
Convert upper 6 bits of byte to ASCIIZ string
of with digits separated with spaces (20h)
like "1 0 1 0 1 0"
Size optimization.
Here is some code for a starter:


SixBits2SpA proc
;IN dl=byte bits,edi=buffer

mov ah,' '
movri ecx,6 ;push 6\pop ecx
@@: shl dl,1
mov al,18h
adc al,al
stosw
loop @B
mov [edi-1],cl
ret

SixBits2SpA endp

Posted on 2003-09-12 12:27:50 by The Svin
Svin, Frankly I'm not sure whether you can optimize your code further in terms of size. Of course I've been known to be wrong from time to time!

BTW, what modr/m decoder optimization problem are you refering to?
Posted on 2003-09-13 18:37:33 by Poimander
That's the conclusion I came to, too. This seems impossible.
Posted on 2003-09-13 19:11:48 by Sephiroth3

BTW, what modr/m decoder optimization
problem are you refering to?


I sent a zip file with sources
of the DecMemr proc and especially
written for testing test app. inside to
rCod2Str thread.

The proc is a quite complex one,
complex term used not to refer to "difficalt"
hence, but in litteral meaning -
the proc deals with complex data (opcode memr tail
that could include modr/m and optionaly
following sib byte and bytes of displacement)
also it has two main branches depending
on 67h prefix:
1. Branch for decoding according 32bit address mode
rules.
2. ... according 16bit address mode rules.

and thus there are lots of control blocks.

If there are any questions regarding opcode format
or decoding rules, or the proc itself - I'll answer
them.

Since opcode format is not those premetives in HLL,
and based of binary fields + it has dinamic size
the problem itself offer many interesting problems
of binary data construction, analisys, decoding,
representing etc.

The simplest problem of decoding problems was
decoding reg names from reg codes, yet
it brought up many interesting ideas I saw
in your code, and others to took part in rCode2Str
optimization.
Full memr field decoding offer even more interesting
problems and hidden opportumities
that's why I thought it'd be an interesting problem
to think about.

Proc inside the zip file is working well, meaning it
writes right operand mnemonic. But it hasn't been
optimized a bit yet.
Posted on 2003-09-13 21:23:37 by The Svin
Right, that was from page #2 of the rCode2Str thread.

The DecMemr procedure is definitely a more complicated optimization problem. However, it might be possible to shorten the code section by section.
Posted on 2003-09-13 23:26:15 by Poimander
I'm not sure whether this is smaller, but its an alternative (and possibly smaller).

Rather than:
mov al, 18h
adc al, al

Use:
setc al
or al, 30h

I don't have MASM to check it with here at the moment...

Mirno
Posted on 2003-09-14 05:29:43 by Mirno
Nope, it is larger.
Posted on 2003-09-14 06:21:48 by Sephiroth3
Mirno
mov reg,imm
-----------
is 1 byte for code block + size of operand for imm.
since it's 8 bits reg - size of imm is 1 byte too.
alltogether it's 2 bytes

adc\add\sub etc. reg,reg
--------------------------
is
1 byte for code byte + 1 byte for modr/m

so it's 2 bytes too.

setc/e/etc. operand
-------------------------
is 1 byte for code and tttn.
at least 1 byte for modr/m (for regs - just one byte modr/m)

or/and/xor ... reg,imm
----------------------
is 1 byte for code
1 byte for modr/m
and at least 1 byte for imm.
so it's 3 bytes minimun.


Poimander

Yes it can be optimized block by block.

I found one stupid error - the proc
forgot checking if mod=00 while handling
base in sib = 101 case.
Couple instr. added to fix.
Here is correct one:
We can start with @mod16 branch - e.i. 16 bit address decoding rules.



DecMemr proc Flags ;IN esi = pointer to modrm
; edi = pointer to string
;OUT edi = next to filled str byte
;esi = pointer to next to memr + ext byte
lodsb ;esi = next to modrm byte
mov ebx,Flags
cmp al,0C0h
jnc @reg
test bl,sbits(2)
je mod32
mod16:
BlockStart
;******************************
;Proc to decode mem/r
;IN eax = modrm
;edi = pointer to string
;esi = next to modr/m
;OUT edi = pointer to next to the last filled byte
;******************************
;here memreg 16
memreg:

@@:
push eax ;save modr/m
and al,11000111b ;check for only displacement
cmp al,6 ;if 00 xxx 110 = only displacement
jne @F
;only displacement------
pop eax
jmp displ16
;-----------------------
@@:
and eax,7 ;extract last 3 bits
push esi ;save pointer to displacement
push 8 ;for ecx
lea esi,[pnames][eax*8]
pop ecx ;ecx=8
cmp eax,4
jc writemem16
and eax,11b
shl eax,2
sub esi,eax
shr ecx,1

writemem16:
rep movsb
pop esi
pop eax
cmp al,80h
jnc displ16
cmp al,40h
jnc displ8
jmp @r
displ8:
mov byte ptr [edi],"["
mov eax,[esi]
test al,al
jns @F
mov byte ptr [edi+1],"-"
inc edi
neg al
@@:

call Word2H
shr eax,16
mov [edi+1],ax
mov word ptr [edi+3],"]h"
add edi,5
inc esi
jmp @r
displ16:
mov eax,[esi]
mov byte ptr [edi],"["

call Word2H
mov [edi+1],eax
mov word ptr [edi+5],"]h"
add edi,7
add esi,2
jmp @r
pnames:
db '[BX][SI][BX][DI][BP][SI][BP][DI][SI][DI][BP][BX]'
BlockEnd
mod32:
BlockStart
;IN ebx Flags, al = modrm, edi = pointer to str, esi - next to modrm
mov bl,al ;bl - modrm
movzx edx,al ;edx = modrm
and edx,7 ;extract memr
cmp edx,100b ; is sib ?
je @sib
cmp edx,101b ; memr= 101 and mod = 0?
jne @simptr
cmp bl,sn(01 000 000y)
jc @disp32 ;mod = 00
@simptr:
call @writepointer
@testdisp:

cmp bl,sn(10 000 000y);if mod = 10
jnc @disp32
cmp bl,sn(01 000 000y);if mod = 01
jnc @disp8
;else - it is mod = 00 no need to write displacement
jmp @r
@disp32:
mov byte ptr [edi],"["
incr 7
lodsd
@1: pushr 0
shr eax,16
invoke Word2H
stosd
popr 0
invoke Word2H
stosd
mov byte ptr [edi],"]"
inc edi
jmp @r
@disp8:

mov byte ptr [edi],"["
incr 7
lodsb
movsx eax,al
jmp @1

@sib:
movzx edx,byte ptr [esi]
and edx,sn(00 111 000y)
shr edx,3
cmp edx,100b ;if no index
je @writebase
;write index
call @writepointer
movzx ecx,byte ptr [esi]
shr ecx,6
je @writebase
push 1
popr 0
add cl,8
shl eax,cl
or eax,"]0*"
mov [edi-1],eax
add edi,2
@writebase:
movzx edx,byte ptr [esi]
incr 6 ;esi to displacement
and edx,7
mov al,byte ptr [esi-2]
cmp al,sn(01 000 000y)
jnc @F
cmp edx,101b
je @disp32
@@:
call @writepointer
jmp @testdisp

@writepointer:
mov byte ptr [edi],"["
inc edi
invoke rCode2Str,01
mov byte ptr [edi],"]"
inc edi
retn
BlockEnd
@r:
ret

@reg:
BlockStart
xchgar 2
and edx,7
invoke rCode2Str,ebx
jmp @r
BlockEnd
DecMemr endp
Posted on 2003-09-14 09:11:17 by The Svin
To understand rules of 16bit address decoding - there are couple
reference apps in "Opcode #7" thread
I've started final app and almost finished reference part -
it could help understand both 16 and 32 bits addr. decoding rules
Posted on 2003-09-16 10:30:08 by The Svin
Forgot to update hex for modrm hex byte
Here it's updated
Posted on 2003-09-16 11:18:44 by The Svin