flat assembler
Message board for the users of flat assembler.

Index > Main > Byte to hex, once again.

Goto page Previous  1, 2, 3  Next
Author
Thread Post new topic Reply to topic
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 17 Aug 2010, 06:02
Code:
Byte2Hex:
            rol ax, 4
            shr al, 4
            call @F
            xchg al, ah
    @@:     and al, 0Fh
            cmp al, 9
            cmc
            sbb dl, dl
            and dl, 7
            add al, dl
            add al, '0'
            ret    
29 bytes and returns what I believe it is the correct answer.

Code:
Byte2Hex:
            mov ah, al
            shr al, 4
            call @F
            xchg al, ah
            and al, 0Fh
    @@:     cmp al, 9
            cmc
            sbb dl, dl
            and dl, 7
            add al, dl
            add al, '0'
            ret    
27 bytes, but gives reversed result as Picnic's code does.

Both codes are of course strongly based on Picnic's code. Very Happy
Post 17 Aug 2010, 06:02
View user's profile Send private message Reply with quote
Alphonso



Joined: 16 Jan 2007
Posts: 295
Alphonso 17 Aug 2010, 09:45
LocoDelAssembly wrote:
29 bytes and returns what I believe it is the correct answer.

The preferred way, whether it's the correct way is IMO up to Fanael to confirm if high and low ordering is required. Fanael would you also clarify if using the stack is allowed?

Nice code examples guys. Smile
Post 17 Aug 2010, 09:45
View user's profile Send private message Reply with quote
Fanael



Joined: 03 Jul 2009
Posts: 168
Fanael 17 Aug 2010, 11:25
p=117915 (Alphonso), p=117916 (LocoDelAssembly): accepted.

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.
Alphonso wrote:
Fanael would you also clarify if using the stack is allowed?
Fourth rule says it's not.

Picnic, LocoDelAssembly: your codes are violating second (call is an unconditional branch, yes, but nonetheless a branch) and fourth (stack!) rule.

Okay, maybe it's time to relax the rules a little bit. New rules (the competition with original rules is still running, though):
* The code has to compile fine with use32 and use64,
* No conditional branches,
* The same goes for conditional moves,
* No memory accesses, except using stack and writing the result somewhere.

According to these rules, I can do nothing else than accept your codes Wink
Post 17 Aug 2010, 11:25
View user's profile Send private message Reply with quote
mindcooler



Joined: 01 Dec 2009
Posts: 423
Location: Västerås, Sweden
mindcooler 17 Aug 2010, 12:52
Picnic wrote:
28 bytes for 32/64. Routine must be called.
Code:
            call @F
    


I thought of doing something like this to make it loop once.

You could do an explicit returnaddress push at the start to make it inlineable.

_________________
This is a block of text that can be added to posts you make.
Post 17 Aug 2010, 12:52
View user's profile Send private message Visit poster's website MSN Messenger ICQ Number Reply with quote
edfed



Joined: 20 Feb 2006
Posts: 4330
Location: Now
edfed 17 Aug 2010, 14:39
or make it loop as many cases you want...

Code:
call @f
xchg al,ah
call @f
xchg al,bl
call @f
xchg al,bh
@@:
ret
    


excellent code.

maybe a rule would be to imposre the conversion of a single byte in AL, and return the result in AX.

or convert the byte from a memory indexed by ESI, and write in a memory indexed by EDI. with a count of bytes to convert in ECX.
Post 17 Aug 2010, 14:39
View user's profile Send private message Visit poster's website Reply with quote
Alphonso



Joined: 16 Jan 2007
Posts: 295
Alphonso 17 Aug 2010, 15:59
Probably as much as I can do with mul.
Code:
         xor    ecx,ecx
         mov    bx,3030h
         mov    cl,7
         mov    ah,al
         shr    ah,4
         and    al,0fh
         add    ebx,eax
         mul    ecx
         shr    ax,6
         and    al,1
         mul    ecx
         add    ebx,eax  ;bx=Ascii    
29 Bytes.
Post 17 Aug 2010, 15:59
View user's profile Send private message Reply with quote
MHajduk



Joined: 30 Mar 2006
Posts: 6115
Location: Poland
MHajduk 17 Aug 2010, 22:20
28 bytes, ASCII output in AX
Code:
xor  ebx, ebx
mov dl, 9

mov        ah, al
shr   ah, 4
and    al, 0Fh
 
cmp     dl, al
adc   bl, bl

cmp       dl, ah
adc   bh, bh

add       ax, 0x3030
imul      ebx, ebx, 7 
add     eax, ebx    
Post 17 Aug 2010, 22:20
View user's profile Send private message Visit poster's website Reply with quote
guignol



Joined: 06 Dec 2008
Posts: 763
guignol 18 Aug 2010, 02:40
Code:
        mov  ah,al
        shr  ah,4
        and  al,0xF

        add  ax,0x4141
        cmp  al,0x4A
        jnbe @f
        sub  al,0x11
     @@:
        cmp  ah,0x4A
        jnbe @f
        sub  ah,0x11
     @@:

; 25 bytes    


Last edited by guignol on 18 Aug 2010, 17:47; edited 5 times in total
Post 18 Aug 2010, 02:40
View user's profile Send private message Reply with quote
MHajduk



Joined: 30 Mar 2006
Posts: 6115
Location: Poland
MHajduk 18 Aug 2010, 08:37
Unfortunately, guignol, your program compiles to 29 bytes for 32 and 64-bit mode (add use32 or use64 at the beginning of your code to check it). Wink Like that:
Code:
use32 ; use64
;
; guignol's code here...
;
    
BTW, you can't use conditional branches. Wink
Post 18 Aug 2010, 08:37
View user's profile Send private message Visit poster's website Reply with quote
Fanael



Joined: 03 Jul 2009
Posts: 168
Fanael 18 Aug 2010, 10:09
Alphonso: accepted.
MHajduk: accepted.
guignol: rejected, conditional branches are not allowed.

Current standings (parenthesized submissions conform only to relaxed rules):
Code:
(1. LocoDelAssembly #4 - 27)
 2. MHajduk - 28
(2. Picnic - 28)
(4. LocoDelAssembly #3 - 29)
 4. Alphonso #3 - 29
 6. Alphonso #2 - 31
 6. LocoDelAssembly #2 - 31
 8. LocoDelAssembly #1 - 33
 9. Alphonso #1 - 37
 10. chaoscode - 49    
Post 18 Aug 2010, 10:09
View user's profile Send private message Reply with quote
guignol



Joined: 06 Dec 2008
Posts: 763
guignol 18 Aug 2010, 10:20
MHajduk wrote:
Unfortunately, guignol, your program compiles to 29 bytes for 32 and 64-bit mode
Very Happy

MHajduk wrote:
BTW, you can't use conditional branches. Wink
At least, [my] code is readable Wink

Code:
mov     dl, 9    
what is this for?
Post 18 Aug 2010, 10:20
View user's profile Send private message Reply with quote
MHajduk



Joined: 30 Mar 2006
Posts: 6115
Location: Poland
MHajduk 18 Aug 2010, 11:04
guignol wrote:
At least, [my] code is readable Wink
Hmm... I was sure that my code is so simple, obvious and trivial (maybe even boring...) that all comments are needless.Image

guignol wrote:
Code:
mov     dl, 9    
what is this for?
It's used here
Code:
cmp     dl, al 
adc     bl, bl 

cmp     dl, ah 
adc     bh, bh    
to reverse compared arguments. Wink

(I mean, that we can't just write something like that: 'cmp 9, al').
Post 18 Aug 2010, 11:04
View user's profile Send private message Visit poster's website Reply with quote
guignol



Joined: 06 Dec 2008
Posts: 763
guignol 18 Aug 2010, 11:12
MHajduk wrote:
Hmm... I was sure that my code is so simple, obvious and trivial
Trivial? maybe, but not obvious.

guignol wrote:
to reverse compared arguments. Wink
I can see that.
What for?
Post 18 Aug 2010, 11:12
View user's profile Send private message Reply with quote
MHajduk



Joined: 30 Mar 2006
Posts: 6115
Location: Poland
MHajduk 18 Aug 2010, 11:23
guignol wrote:
I can see that.
What for?
We need CF flag set for al >= 10 and ah >= 10.

When al >= 10 (ah >= 10) then bl (bh) is set to 1 (we can use here one of the 'setX' instructions, but it would give 3 bytes here instead 2 for 'adc bl, bl' and 'adc bh, bh'). Smile
Post 18 Aug 2010, 11:23
View user's profile Send private message Visit poster's website Reply with quote
guignol



Joined: 06 Dec 2008
Posts: 763
guignol 18 Aug 2010, 11:52
MHajduk wrote:
We need CF flag set for al >= 10 and ah >= 10.

When al >= 10 (ah >= 10) then bl (bh) is set to 1 (we can use here one of the 'setX' instructions, but it would give 3 bytes here instead 2 for 'adc bl, bl' and 'adc bh, bh'). Smile
Don't try to outweird me, baby!
I'm asking why do you use some register instead of an immediate value?
Post 18 Aug 2010, 11:52
View user's profile Send private message Reply with quote
MHajduk



Joined: 30 Mar 2006
Posts: 6115
Location: Poland
MHajduk 18 Aug 2010, 12:13
"Baby", that's good, hahaha... Laughing

You can all do comparisons this way:
Code:
cmp al, 10

(...)

cmp ah, 10    
and spare 2 bytes for 'mov dl, 9', but... 'cmp ah, 10' takes 3 bytes, inequalities are reversed, so you have to exchange al & ah to "spare" one byte... doing 'xchg al, ah' you "produce" one extra byte instead.

To reverse inequalities you have to use two 'cmc' (2 extra bytes) or something like that - that is a monkey business. I tried it all yesterday and I'm almost sure that we probably can't minimize it further. Confused


It would be superb if we can use such instructions like 'aam 16' (only two bytes!) to separate al nibbles:
Code:
aam 16; ah := al / 16, al := al mod 16    
but we can't (in 64 bit mode). Wink

[EDIT]Corrected typo '%' -> '/'[/EDIT]


Last edited by MHajduk on 21 Aug 2010, 14:04; edited 1 time in total
Post 18 Aug 2010, 12:13
View user's profile Send private message Visit poster's website Reply with quote
guignol



Joined: 06 Dec 2008
Posts: 763
guignol 18 Aug 2010, 12:41
Code:
         mov  dl,9
         cmp  dl,al
         cmp  dl,ah
; 6 bytes    
Code:
        cmp  al,10
        cmp  ah,10

; 5 bytes    
Post 18 Aug 2010, 12:41
View user's profile Send private message Reply with quote
MHajduk



Joined: 30 Mar 2006
Posts: 6115
Location: Poland
MHajduk 18 Aug 2010, 13:00
guignol wrote:
Code:
         mov  dl,9
         cmp  dl,al
         cmp  dl,ah
; 6 bytes    
Code:
        cmp  al,10
        cmp  ah,10

; 5 bytes    
Yeah, but I've told you above that these "spared" bytes are wasted somewhere else then. See
Code:
cmp al, 10; CF = 1 when al < 10, CF = 0 when al >= 10    
i.e. exactly we have inversion of what we expected:
Code:
;
;"cmp 10, al"
;
cmp reg8, al ; CF = 1 when reg8 < al, CF = 0 when reg8 >= al
               ; i.e. CF = 1 when al > reg8, CF = 0 when al <= reg8

              ; If reg8 = 9 we have exactly what was expected:
                ; CF = 1 when al > 9, CF = 0  when al <= 9
            ; i.e. CF = 1 when al >= 10, CF = 0 when al < 10

    
and doing 'adc bl, bl' and 'adc bh, bh' would be nonsense after 'cmp al, 10' and 'cmp ah, 10' respectively. Wink
Post 18 Aug 2010, 13:00
View user's profile Send private message Visit poster's website Reply with quote
guignol



Joined: 06 Dec 2008
Posts: 763
guignol 18 Aug 2010, 14:09
MHajduk wrote:
and doing 'adc bl, bl' and 'adc bh, bh' would be nonsense after 'cmp al, 10' and 'cmp ah, 10' respectively. Wink
That's why they have jumps Wink
But some falafel won't like them. I bet! it's hard to jump when you're round. Laughing

Ok.
Code:
add     ax, 0x3030
imul    ebx, ebx, 7  
add     eax, ebx    
What is this?
You add 7 to 48?
Post 18 Aug 2010, 14:09
View user's profile Send private message Reply with quote
MHajduk



Joined: 30 Mar 2006
Posts: 6115
Location: Poland
MHajduk 18 Aug 2010, 14:39
guignol wrote:
But some falafel won't like them.
Hehe, Falafel. Laughing You've just "degraded" one of the archangels (Phanuel) to the common Arabic dish. Wink

BTW, thinking of Fanael's nick, I got that there should exist an angel who cares about FASM coders. I guess he/she should be named Fasmael. Wink Razz

guignol wrote:
Code:
add     ax, 0x3030
imul    ebx, ebx, 7  
add     eax, ebx    
What is this?
You add 7 to 48?
After all comparisons we have:
Code:
       /
      | 0, if al < 10
bl = <
      | 1, if al >= 10
       \


       /
      | 0, if ah < 10
bh = <
      | 1, if ah >= 10
       \
    
i.e. bl and bh contain information about numbers stored in al and ah respectively. Operation
Code:
add     ax, 0x3030    
converts numbers in al and ah into ASCII, but this is not correct for al, ah from the set {0xA, ..., 0xF} because we get 0x3A, ..., 0x3F instead expected 0x41, ..., 0x46.
So, we need correction equal to 7 for al, ah >= 0x3A. This is performed in the next two instructions:
Code:
imul    ebx, ebx, 7  
add     eax, ebx    
after 'imul ebx, ebx, 7' we have:
Code:
       /
      | 0, if al < 0x3A
bl = <
      | 7, if al >= 0x3A
       \


       /
      | 0, if ah < 0x3A
bh = <
      | 7, if ah >= 0x3A
       \
    
Now, everything should be clear. Wink
Post 18 Aug 2010, 14:39
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page Previous  1, 2, 3  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.