Back to home page

DOS ain't dead

Forum index page

Log in | Register

Back to index page
Thread view  Board view
DOS386(R)

13.04.2009, 10:20
 

18 Bytes !!! Anyone can beat this? HEX16 for 8086 (Developers)

Task: convert the value in DX (or some other register) into a 4-Bytes string representing the number in HEX using 8086 compatible instructions (no TSR this time, sorry :crying:)

Solution by King Udo (31 Bytes):

output_hex:

; On Entry:
;      dx = 2 byte hex value
; On Exit:
;      None

        mov      cx,4
output_hex10:
        mov      al,dh
        push     cx
        mov      cl,4
        shr      al,cl
        pop      cx
        and      al,0fh
        cmp      al,09h         ; greater 0-9?
        jg       output_hex20
        add      al,30h
        jmp      output_hex30
output_hex20:
        add      al,37h
output_hex30:
        ; call onecharal
        push     cx
        mov      cl,4
        shl      dx,cl
        pop      cx
        loop     output_hex10


My solution (18 Bytes):

use16

; HEX16 output conversion, 8086 compatible

; Input in DX or AX | Trashes AX CX DX

;  9 instructions 18 Bytes vary bare input in DX
; 10 instructions 19 Bytes very bare input in AX
; 11 instructions 22 Bytes including call, input in AX
; 18 instructions 29 Bytes including call, full register preservation and RET

        push   ax
        push   cx
        push   dx

        xchg   dx, ax       ; DX <- AX | Later peek the 4-bit groups from DX
        mov    cx, 1028     ; "MOVNTQ CL, 4" + "MOVNTQ CH, 4"
@@:     mov    al, dh       ; AL <- DH | Move all 8 bits, only upper 4 useful
        shl    dx, cl       ; 8086 compatible
        shr    al, cl       ; 8086 compatible
        cmp    al, 10       ; Now must be and is AL<=15 | Decimal "10" !!!
        sbb    al, $69      ; Securely Bugged Backup
        das                 ; Digital Attack System | ASCII result in AL
        call   onecharal    ; Input in AL | Must preserve CX and DX, not AX
        dec    ch           ; & No LOO'p on CH :-(
        jnz    short @b     ; &

        pope   dx
        pope   cx
        pope   ax
        ret
        ;----

---
This is a LOGITECH mouse driver, but some software expect here
the following string:*** This is Copyright 1983 Microsoft ***

cm(R)

Homepage E-mail

Düsseldorf, Germany,
13.04.2009, 14:08

@ DOS386
 

18 Bytes! Anyone can beat this? - No

My solution requires 34 bytes, but I think it's easier to understand than using das (or daa, see below).

disp_ax_hex:                      ; ax
                xchg al,ah
                call disp_al_hex                ; display former ah
                xchg al,ah                      ;  and fall trough for al
disp_al_hex:                    ; al
                push cx
                mov cl,4
                ror al,cl
                call disp_al_lownibble_hex      ; display former high-nibble
                rol al,cl
                pop cx
                                                ;  and fall trough for low-nibble
disp_al_lownibble_hex:
                push ax                         ; save ax for call return
                and al,00001111b                ; high nibble must be zero
                add al,'0'                      ; if number is 0-9, now it's the correct character
                cmp al,'9'
                jna .decimalnum                 ; if we get decimal number with this, ok -->
                add al,7                        ;  otherwise, add 7 and we are inside our alphabet
 .decimalnum:
                call disp_al
                pop ax
                retn


I think Henrik Haftmann's solution is good, too. It still requires 26 bytes. (Note that _ochr is actually the call to display the character in al, so it doesn't count. Note also that these macros aren't used as macros multiple times per program, they're used once, then they're called inside the program.)

macro _ochr                       ;Zeichenausgabe aus AL
ochr:   push    ax dx
        mov     dl,al
        DOS     2
        pop     dx ax
        ret
        endm

macro _axhx                     ;Hexzahlausgabe, VR: AX,F
axhx:   xchg    al,ah
        call    ahex
        xchg    al,ah
ahex:   push    ax cx           ;Werte erhalten
        mov     cl,4            ;oberes Nibble auf Bit 3...0
        shr     al,cl           ; schieben
        pop     cx
        call    ahex1
        pop     ax
ahex1:  and     al,0fh
        add     al,90h          ;Hex -> ASCII
        daa
        adc     al,40h
        daa
        _ochr
        endm

---
l

DOS386(R)

13.04.2009, 14:32

@ cm
 

18 Bytes! Anyone can beat this? - No DAS

> easier to understand than using das

Just replace (5 Bytes):

        cmp    al, 10       ; Now must be and is AL<=15 | Decimal "10" !!!
        sbb    al, $69      ; Securely Bugged Backup
        das                 ; Digital Attack System | ASCII result in AL


by (8 Bytes):

        cmp    al, 10
        jb      short heh
        add     al, 7
heh:    add     al, 48


So my code grows to 21 Bytes. I have no idea how DAS works but it does :clap:

---
This is a LOGITECH mouse driver, but some software expect here
the following string:*** This is Copyright 1983 Microsoft ***

rr(R)

Homepage E-mail

Berlin, Germany,
13.04.2009, 16:13

@ DOS386
 

18 Bytes! Anyone can beat this? - No DAS

> So my code grows to 21 Bytes. I have no idea how DAS works but it
> does :clap:

http://www.df.lth.se/%7Ejohn_e/gems/gem003a.html

mht(R)

Homepage

Wroclaw, Poland,
13.04.2009, 16:04

@ DOS386
 

18 Bytes !!! Anyone can beat this? HEX16 for 8086

You can still improve register usage. Use rotations on one register instead of shifts on two (4 rotations by 4 bits = no-op).
But anyway, what are you trying to show?
1. "Work-In-Progress version" certainly may contain some (possibly even unused) debug code and there is nothing wrong with it.
2. Optimizing such pieces of code is wasting time, it will be surely removed in a "production" version.
3. You can find source files where unclear tricks (like the old DAS one) are commented and explained, better cut-and-paste from there, instead of introducing additional noise.

DOS386(R)

18.05.2009, 05:54
(edited by DOS386, 18.05.2009, 06:09)

@ mht
 

18 Bytes !!! Anyone can beat this? HEX16 for 8086 | ROL

rr wrote:

> http://www.df.lth.se/%7Ejohn_e/gems/gem003a.html

:-)

mht wrote:

> You can still improve register usage. Use rotations on one
> register instead of shifts on two (4 rotations by 4 bits = no-op).

Thanks :-) You can't beat the 18 Bytes this way but indeed improve the "useful" variant :-)

> better cut-and-paste from there, instead of introducing additional
> noise

Welcome back to NOiSe ain't dead - the great C&P forum :confused:

use16

; HEX16 output conversion, 8086 compatible

; Input in AX | Trashes CX only !!!

;  9 instructions 18 Bytes vary bare, input in DX, trashes AX
; 10 instructions 18 Bytes very bare, input in AX, uses stack
; 10 instructions 19 Bytes very bare, input in AX, trashes DX, no stack
; 11 instructions 21 Bytes including call, input in AX, uses stack
; 14 instructions 24 Bytes including call, full register preservation and RET

hex16:
        push   cx

        mov    cx, 1028     ; "MOVNTQ CL, 4" + "MOVNTQ CH, 4"
h16l:
        rol    ax, cl       ; 8086 compatible, after 4 ROL's original back
        ; rol    dx, cl       ; 8086 compatible, after 4 ROL's original back
        ; mov    al, dl       ; AL <- DL , transfer 8 bits, only 4 are useful
        push   ax
        ; mov    dx, ax       ; Now both DX and AX are equal, XCHG not good
        and    al, $0F
        cmp    al, 10       ; Now must be and is AL<=15 | Decimal "10" !!!
        sbb    al, $69      ; Securely Bugged Backup
        das                 ; Digital Attack System | ASCII result in AL
        call   onecharal    ; Input in AL | Must preserve CX (+ DX or AX)
        pope   ax
        ; xchg   dx, ax       ; Restore trashed AX from DX, but now DX trash
        dec    ch           ; & No LOO'p on CH :-(
        jnz    short h16l   ; &

        pope   cx
        ret
        ;----

; Avoiding cryptic "DAS" (also preceding SBB, OTOH keep CMP) costs 3 Bytes:

        cmp    al, 10
        jb     short @f     ; OK, 0 ... 9
        add    al, 7        ; Fix for A ... F
@@:     add    al, 48

---
This is a LOGITECH mouse driver, but some software expect here
the following string:*** This is Copyright 1983 Microsoft ***

Back to index page
Thread view  Board view
15109 Postings in 1359 Threads, 247 registered users, 9 users online (1 registered, 8 guests)
DOS ain't dead | Admin contact
RSS Feed
powered by my little forum