flat assembler
Message board for the users of flat assembler.

 Index > Main > Byte to hex, once again. Goto page Previous  1, 2, 3
Author
Alphonso

Joined: 16 Jan 2007
Posts: 295
Alphonso 18 Aug 2010, 16:09
Nice use of imul MHajduk. guignol would it help if dl was not used at all. When trying to minize code it can often look unobvious.
Code:
xor     ebx, ebx
mov     ah, al
shr     ah, 4
and     al, 0Fh
imul    ebx,ebx,7
This isn't an entry BTW.

But inspired by MHajduk this is.
Code:
mov    ah,al
shr    ah,4
and    al,0fh
imul   ebx,eax,7
shr    bx,6
and    bl,1
imul   ebx,ebx,7
26 Bytes.
18 Aug 2010, 16:09
guignol

Joined: 06 Dec 2008
Posts: 763
guignol 18 Aug 2010, 17:22
MHajduk
Simple yes, would have been enough.
Me haved glitch
18 Aug 2010, 17:22
MHajduk

Joined: 30 Mar 2006
Posts: 6115
Location: Poland
MHajduk 18 Aug 2010, 17:30
Code:
imul   ebx, eax, 7
shr    bx, 6
and    bl, 1

My Gosh, why I haven't paid notice to this... Now I understand "magic" of the 7 :
Code:
imul   ebx, eax, 7 ; ebx := eax * 7
;
; i.e. bh := ah * 7, bl := al * 7
;
; for al, ah from the set {0, ..., 9} we have {0, 7, ..., 63}
;
; for al, ah from the set {0xA, ..., 0xF} we have values presented below:
;
; 7*10 = 70  = 1000110b
; 7*11 = 77  = 1001101b
; 7*12 = 84  = 1010100b
; 7*13 = 91  = 1011011b
; 7*14 = 98  = 1100010b
; 7*15 = 105 = 1101001b
;
; i.e. bit No. 6 of the bl (bh) register is equal to 1 if and only if
; al >= 0xA (ah >= 0xA respectively)

shr    bx, 6            ; Now bh = 1 iff ah >= 0xA, but bl contains in the 6 most significant bits
; some "garbage" from the bh, so we need...

and    bl, 1               ; ... some cleaning. Now also bl = 1 iff al >= 0xA
Chapeau bas, Alphonso.

Last edited by MHajduk on 21 Aug 2010, 14:00; edited 1 time in total
18 Aug 2010, 17:30
Fanael

Joined: 03 Jul 2009
Posts: 168
Fanael 18 Aug 2010, 17:53
guignol wrote:
That's why they have jumps
The competition would become too easy if we could use jcc

18 Aug 2010, 17:53
MHajduk

Joined: 30 Mar 2006
Posts: 6115
Location: Poland
MHajduk 18 Aug 2010, 18:33
25 bytes, ASCII output in AX register (but with bytes in the reversed order):
Code:
xor    ah, ah
mov   bl, 16
div   bl

imul  ebx, eax, 7
shr     bx, 6
and   bl, 1

imul      ebx, ebx,7
Since ordering is not significant, I guess my current proposition should be accepted:
Fanael wrote:
Alphonso wrote:
The preferred way, whether it's the correct way is IMO up to Fanael to confirm if high and low ordering is required.
No specific ordering is required, the only requirements is that both characters are ASCII.
18 Aug 2010, 18:33
bitshifter

Joined: 04 Dec 2007
Posts: 796
Location: Massachusetts, USA
bitshifter 19 Aug 2010, 02:53
Very cool topic!

24 bytes, based on MHajduk last entry (saved 1 byte)
Code:
mov     ah,0
mov     bl,16
div     bl

imul    ebx,eax,7
shr     ebx,6
and     bl,1

imul    ebx,ebx,7

19 Aug 2010, 02:53
LocoDelAssembly

Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 19 Aug 2010, 04:42
bitshifter, set EAX to \$12345678 and see what you get in AX after executing your version.
19 Aug 2010, 04:42
bitRAKE

Joined: 21 Jul 2003
Posts: 4020
Location: vpcmpistri
bitRAKE 19 Aug 2010, 06:17
Code:
mov ah, al
and al, 0Fh
shr ah, 4

cmp al, 10
sbb bl, bl
cmp ah, 10
sbb bh, bh

and bx, \$0707
sub eax, ebx
27 bytes, 10 instructions.

MHajduk, "SHR EBX,6" saves a byte. Too bad "AAM 16" is no good in 64-bit.

Edit: Okay, SHR EBX,6 does not work because of higher bits after IMUL.

Down to 8 instructions,
Code:
xor     ah, ah
mov     bl, 16
div     bl

imul    ebx, eax, 7
shr     bx, 6
and     bl, 1

;lea eax,[eax+8*ebx+'00'] ; 32 bit
lea eax,[rax+8*rbx+'00'] ; 64 bit
sub eax,ebx
25 bytes

16/32-bit only solution:
Code:
aam 16

imul ebx, eax, 7
shr bx, 6
and bl, 1

lea eax,[eax+8*ebx+'00']
sub eax,ebx
Good trick Alphonso.
19 Aug 2010, 06:17
Fanael

Joined: 03 Jul 2009
Posts: 168
Fanael 19 Aug 2010, 12:05
bitshifter: rejected, invalid result.
bitRAKE: first code accepted, second code will be accepted, if you will surround that lea with some compile-time if checking current bitness.
19 Aug 2010, 12:05
edfed

Joined: 20 Feb 2006
Posts: 4330
Location: Now
edfed 19 Aug 2010, 15:58
bitshifter, instead of mov ah,0, use movzx eax,al

it will be 25 bytes, but it will noit be rejected by the judge.
19 Aug 2010, 15:58
bitRAKE

Joined: 21 Jul 2003
Posts: 4020
Location: vpcmpistri
bitRAKE 20 Aug 2010, 05:14
There are many compile-time methods, this one just uses the instruction in question:
Code:
mov al,\$00

xor ah,ah
mov bl,16
div bl

imul ebx,eax,111b
shr bx,6
and bl,1

virtual at 0
lea eax,[eax+8*ebx+'00']
end virtual
if _USE__ and \$FF = \$8D
; use32
lea eax,[eax+8*ebx+'00']
else if _USE__ shr 8 and \$FF = \$8D
; use64
lea eax,[rax+8*rbx+'00']
else
; use16
imul bx,bx,7
end if

sub eax,ebx
...which leads to mode specific methods in whole, or the question of a universal encoding - the same bytes working across processing modes. Many of the byte orientated encoding enjoy this distinction of universality.
20 Aug 2010, 05:14
edfed

Joined: 20 Feb 2006
Posts: 4330
Location: Now
edfed 14 Sep 2010, 13:56
just played with the snippets in this board, and i finaly coded something like clock monitoring for contests.

based on fool, but ok for little snippets comparisions.

Code:
include 'comsys.inc'
B2H:    Node .time,.fxdec,.label,.asm,.txt,.keys

.number:
dd 0
.sel:
dd 0
.label: Txt 10,0,0,0,Blue,0,1,font85
.time:  Txt 10,15,0,0,Green,.ticks,1,font85
.txt:   Txt 0,0,0,0,Red,.hex,10,font85
.keys:  Node .otk,.tmk
.otk:   dd f.otk,0,@f-\$-4
dd key.up,.decsel
dd key.down,.incsel
@@:
.tmk:   dd f.tmk,0,@f-\$-4
dd key.right,.incnum
dd key.left,.decnum
@@:
.incnum:
Asm incd,.number
.decnum:
Asm decd,.number

.decsel:
Asm @f
@@:
mov eax,[.list+list.size]
sub eax,4
sub dword[.sel],4
jge @f
mov [.sel],eax
@@:
ret
align 4
.incsel:
Asm @f
@@:
mov eax,[.list+list.size]
cmp [.sel],eax
jl @f
mov dword[.sel],0
@@:
ret
align 4
.fxdec: dd f.fxdec,.clocks+4,.ticks,.ticksz
.asm:   Asm .B2H
.hex:   db ' '
@@:     db '00',0
.ticks: db '123456789'
.ticksz: db ' clocks',0
.B2H:
push eax
call .disp
mov al,[.number]
call .func
mov [@b],ax
mov dword[mouse.item],0   ;disable mouse
pop eax
ret

.func:
push ebx
push eax
mov ebx,0
call .rdtsc0
call word [.list+list.data+ebx]
call .rdtsc1
pop eax
mov ebx,[.sel]
call .rdtsc0
call word [.list+list.data+ebx]
call .rdtsc1
call .mean
pop ebx
ret
.rdtsc0:
push eax edx
rdtsc
mov [.clocks],eax
pop edx eax
ret
.rdtsc1:
push eax edx
rdtsc
sub eax,[.clocks]
mov [.clocks],eax
pop edx eax
ret
.mean:
push eax
mov eax,[.clocks]
inc byte[.clocks+8]
cmp byte[.clocks+8],64
jne @f
mov byte[.clocks+8],0
mov eax,[.clocks+12]
mov dword[.clocks+12],0
shr eax,6
mov [.clocks+4],eax
@@:
pop eax
ret

.clocks:
dd 0,0,0,0
.disp:
mov eax,[.sel]
mov eax,[eax+.list+list.data]
mov eax,[eax-4]
mov [.label+txt.txt],eax
ret

align 4
.list:  List \
empty,\
alphonso,\
bitrake0,\
bitrake,\
bitshifter,\
edfed,\
loco0,\
loco,\
mhajduk0,\
mhajduk
;;;;;;;;;;;;;;;;;;;;;;
@@:   db 'empty',0
align 4
dd @b
empty:
mov ax,'ZZ'
ret
;;;;;;;;;;;;;;;;;;;;;;
@@:   db 'bitRAKE',0
align 4
dd @b
bitrake:
include 'B2H-bitrake.inc'
ret
;;;;;;;;;;;;;;;;;;;;;;
@@:   db 'bitRAKE 0',0
align 4
dd @b
bitrake0:
include 'B2H-bitrake0.inc'
ret
;;;;;;;;;;;;;;;;;;;;;;
@@:   db 'Alphonso',0
align 4
dd @b
alphonso:
include 'B2H-Alphonso.inc'
ret
;;;;;;;;;;;;;;;;;;;;;;
@@:   db 'bitshifter',0
align 4
dd @b
bitshifter:
include 'B2H-Bitshifter.inc'
ret
;;;;;;;;;;;;;;;;;;;;;;
@@:   db 'LocoDelAssembly',0
align 4
dd @b
loco:
include 'B2H-loco.inc'
ret
;;;;;;;;;;;;;;;;;;;;;;
@@:   db 'LocoDelAssembly 0',0
align 4
dd @b
loco0:
include 'B2H-loco0.inc'
ret
;;;;;;;;;;;;;;;;;;;;;;
@@:   db 'edfed',0
align 4
dd @b
edfed:
include 'B2H-edfed.inc'
ret
;;;;;;;;;;;;;;;;;;;;;;

@@:   db 'MHajduk',0
align 4
dd @b
mhajduk:
include 'B2H-MHajduk.inc'
ret
;;;;;;;;;;;;;;;;;;;;;;
@@:   db 'MHajduk 0',0
align 4
dd @b
mhajduk0:
include 'B2H-MHajduk0.inc'
ret
;;;;;;;;;;;;;;;;;;;;;;

every snippets picked from this topic are modified in order to work the same.

and the winner on my computer is:

B2H-bitrake0.inc , 378 clocks

followed by:
B2H-bitrake.inc , 390 clocks
B2H-loco0.inc , 395 clocks

350 clocks needed for the launcher and the mesure.

14 Sep 2010, 13:56
edfed

Joined: 20 Feb 2006
Posts: 4330
Location: Now
edfed 16 Sep 2010, 14:46
clocks mesured above are from the aspireone with XP.
when runing under 98 (closer to real hardware) the clocks decrease significantlly.
an there, the speed winner is loco with this algo:

Code:
ror al,4
mov ah,al
shr al, 4
call @F
xchg al,ah
and al,0Fh
@@:
cmp al,10
cmc
sbb dl,dl
and dl,7
ret

executes in 112 clocks, including the 90 clocks overhead for callee.

then, 22 clocks on the PIII deskbook. (yep, i use an open laptop as desktop computer).
16 Sep 2010, 14:46
 Display posts from previous: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First

 Jump to: Select a forum Official----------------AssemblyPeripheria General----------------MainTutorials and ExamplesDOSWindowsLinuxUnixMenuetOS Specific----------------MacroinstructionsOS ConstructionIDE DevelopmentProjects and IdeasNon-x86 architecturesHigh Level LanguagesProgramming Language DesignCompiler Internals Other----------------FeedbackHeapTest Area
Goto page Previous  1, 2, 3

Forum Rules:
 You cannot post new topics in this forumYou cannot reply to topics in this forumYou cannot edit your posts in this forumYou cannot delete your posts in this forumYou cannot vote in polls in this forumYou cannot attach files in this forumYou can download files in this forum