flat assembler
Message board for the users of flat assembler.

Index > DOS > How to convert decimal to 32-bit hex in DOS (for hexdump)?

Goto page 1, 2  Next
Author
Thread Post new topic Reply to topic
FlierMate11



Joined: 13 Oct 2022
Posts: 94
FlierMate11 27 Jan 2023, 10:12
Previously, Tomasz offered his solution to me for 32-bit and 64-bit programming.

Now, I port my hexdump from Windows & Linux to DOS, but limited to 16-bit register, I cannot convert to hexadecimal value larger than 16-bit, at least I don't know how.

Code:
ConvertLongHex:    Wink Nice code snippet by Tomasz Grysztar (flat assembler)
        xor      di,di
        mov     cx, 4
.loop1:
        rol      dx,4
        mov      si,dx
        and      si,1111b
        mov      al,[_digits+si]
        mov      [di+_hexnum],al
        inc      di
        dec      cx
        jnz      .loop1
        ret     
...
...
_hexnum   rb 4
          db '$'
_hexval   rb 2
          db '$'
_digits   db '0123456789ABCDEF' 

    


Can someone enlighten?

This is the 32-bit hex edition:
Code:
ConvertLongHex:    Wink Nice code snippet by Tomasz Grysztar (flat assembler)
        xor      ebx,ebx
        mov     ecx, 8
.loop1:
        rol      edx,4
        mov      eax,edx
        and      eax,1111b
        mov      al,[_digits+eax]
        mov      [ebx+_hexnum],al
        inc      ebx
        dec      ecx
        jnz      .loop1
        ret        


Last edited by FlierMate11 on 27 Jan 2023, 10:17; edited 1 time in total
Post 27 Jan 2023, 10:12
View user's profile Send private message Visit poster's website Reply with quote
FlierMate11



Joined: 13 Oct 2022
Posts: 94
FlierMate11 27 Jan 2023, 10:13
Example output of my hexdump (almost finished except the hexadecimal conversion part, because 16-bit offset only)
Code:
0000  4D 5A 41 00 02 00 01 00 02 00 1F 00 FF FF 32 00   MZA...........2.
0010  00 01 00 00 00 00 00 00 1C 00 00 00 01 00 00 00   ................
0020  B8 1A 00 8E D8 FC 26 0F B6 0E 80 00 26 8D 3E 81   ......&.....&.>.
0030  00 8D 36 81 00 83 F9 00 0F 84 F2 00 26 8A 05 3C   ..6.........&..<
0040  20 75 07 3C 0D 74 09 47 EB F2 88 04 46 47 E2 EC    u.<.t.G....FG..    
Post 27 Jan 2023, 10:13
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20460
Location: In your JS exploiting you and your system
revolution 27 Jan 2023, 10:26
Not enough room for 8 characters.
FlierMate11 wrote:
Code:
_hexnum   rb 4    
Post 27 Jan 2023, 10:26
View user's profile Send private message Visit poster's website Reply with quote
FlierMate11



Joined: 13 Oct 2022
Posts: 94
FlierMate11 27 Jan 2023, 11:11
revolution wrote:
Not enough room for 8 characters.
FlierMate11 wrote:
Code:
_hexnum   rb 4    


Yes, I changed it.

But if I change it back to
Code:
_hexnum   rb 8    

and set "mov cx, 8", this is the "32-bit" hex output (see offset):
Code:
00000000  4D 5A 41 00 02 00 01 00 02 00 1F 00 FF FF 32 00   MZA...........2.
00100010  00 01 00 00 00 00 00 00 1C 00 00 00 01 00 00 00   ................
00200020  B8 1A 00 8E D8 FC 26 0F B6 0E 80 00 26 8D 3E 81   ......&.....&.>.
00300030  00 8D 36 81 00 83 F9 00 0F 84 F2 00 26 8A 05 3C   ..6.........&..<
00400040  20 75 07 3C 0D 74 09 47 EB F2 88 04 46 47 E2 EC    u.<.t.G....FG..
00500050  B0 24 88 04 BA 81 00 B4 09 CD 21 B4 3D 30 C0 BA   .$........!.=0..
00600060  81 00 CD 21 A3 7B 00 0F 82 CC 00 B4 3F 8B 1E 7B   ...!.{......?..{
00700070  00 B9 10 00 BA 67 00 CD 21 A3 77 00 0F 82 C7 00   .....g..!.w.....
00800080  8B 0E 77 00 85 C9 0F 84 9A 00 89 0E 7D 00 8B 16   ..w.........}...
00900090  7F 00 B9 04 00 E8 F3 00 E8 D6 00 E8 BE 00 31 C9   ..............1.
00A000A0  31 D2 89 CE 8A 54 67 51 B9 02 00 E8 F2 00 E8 C7   1....TgQ........    


Do you know what's wrong? Or must use two registers for it?
Post 27 Jan 2023, 11:11
View user's profile Send private message Visit poster's website Reply with quote
FlierMate11



Joined: 13 Oct 2022
Posts: 94
FlierMate11 27 Jan 2023, 11:17
Code:
mov     dx, [_offset]  
mov     cx, 4
call    ConvertLongHex 
    


I forgot to post the "mov dx, [_offset]" in above.

Looks like "rol dx, 4" is the bottleneck.

Anyway, the dx can only contain 16-bit value......
Post 27 Jan 2023, 11:17
View user's profile Send private message Visit poster's website Reply with quote
FlierMate11



Joined: 13 Oct 2022
Posts: 94
FlierMate11 27 Jan 2023, 11:33
I think I will just publish this HEXDUMPD (for DOS version) for small files only (below 64KB) until I have better solution to support large file offset.

Thanks to @macomics and @sinsi for their help in solving command-line arguments in DOS (https://board.flatassembler.net/topic.php?t=22564&start=20), I benefited from it indirectly.

If anyone want to create polyglot EXE, can combine my Hexdump for DOS with Hexdump for Windows.

First, download "hexdumpw.asm" from :
https://board.flatassembler.net/topic.php?t=22184

Change the first line to :
Code:
format PE console on 'HEXDUMPD.EXE'
    


Compile my HEXDUMPD.asm (DOS), and then compile HEXDUMPW.asm (Win32), you'll now have a 2-in-1 EXE.

Can redirect to file:
Code:
hexdumpd abc.exe > b.txt

hexdumpw test.jpg > c.txt
    


Description: Hexdump for DOS (for small file below 64KB)
Download
Filename: HEXDUMPD.ASM
Filesize: 5.22 KB
Downloaded: 276 Time(s)

Post 27 Jan 2023, 11:33
View user's profile Send private message Visit poster's website Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20460
Location: In your JS exploiting you and your system
revolution 27 Jan 2023, 11:45
FlierMate11 wrote:
Do you know what's wrong? Or must use two registers for it?
No. You had only posted random snippets so no way to tell what you did.

But one thing is for sure, you don't need to use two registers if you are running the code on a 32-bit capable machine.
Post 27 Jan 2023, 11:45
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 806
Location: Russian Federation, Sochi
ProMiNick 27 Jan 2023, 12:12
Code:
INT2HEX:
        ;in
        ;si - ptr INT 
        ;cx - size in bytes of int limited by ram occupied by [si] & [di] addressed buffers
        ;di - ptr HEX
        xor     ax, ax
        add     si, cx
       ;mov     dx, cx
        jmp     .cvt_in
    .loop:
        dec     si
        mov     al, [si]
        ror     ax, 4
        shr     ah, 4
        add     ax, $0606
        test    ah,$10
        jz      @F
        add     ah,'A'-'0'-10
      @@:
        test    al,$10
        jz      @F
        add     al,'A'-'0'-10
      @@:
        add     ax, ('0'-6)+('0'-6) shl 8
        stosw
    .cvt_in:
        dec     cx
        jnz     .loop
        mov     [di], cl
       ;sub     di, dx      
Post 27 Jan 2023, 12:12
View user's profile Send private message Send e-mail Reply with quote
FlierMate11



Joined: 13 Oct 2022
Posts: 94
FlierMate11 27 Jan 2023, 12:46
Thanks @ProMiNick, I am still trying to make it work.

Is the "di" register increment (cld) or decrement (std)?

I set the value as below:
Code:
mov     di, _hexnum
mov     si, _offset
mov     cx, 4

...
...
_offset   dd 0 
_hexnum   rb 8
          db '$' 
    


Output is incorrect though:
Code:
    000000   4D 5A 41 00 02 00 01 00 02 00 1F 00 FF FF 32 00   MZA...........2.
    0000000  00 01 00 00 00 00 00 00 1C 00 00 00 01 00 00 00   ................
    0000000  B8 1A 00 8E D8 FC 26 0F B6 0E 80 00 26 8D 3E 81   ......&.....&.>.
    0000001  00 8D 36 81 00 83 F9 00 0F 84 F2 00 26 8A 05 3C   ..6.........&..<
    000000C  20 75 07 3C 0D 74 09 47 EB F2 88 04 46 47 E2 EC    u.<.t.G....FG..
    000000C  B0 24 88 04 BA 81 00 B4 09 CD 21 B4 3D 30 C0 BA   .$........!.=0..
    000000A  81 00 CD 21 A3 7B 00 0F 82 CC 00 B4 3F 8B 1E 7B   ...!.{......?..{
    000000B  00 B9 10 00 BA 67 00 CD 21 A3 77 00 0F 82 C7 00   .....g..!.w.....
    0000000  8B 0E 77 00 85 C9 0F 84 9A 00 89 0E 7D 00 8B 16   ..w.........}...
    0000006  7F 00 B9 04 00 E8 F3 00 E8 D6 00 E8 BE 00 31 C9   ..............1.
    0000009  31 D2 89 CE 8A 54 67 51 B9 02 00 E8 F2 00 E8 C7   1....TgQ........
    0000007  00 E8 AF 00 59 41 3B 0E 7D 00 72 E4 83 F9 10 72   ....YA;.}.r....r
    0000002  02 EB 11 BB 10 00 29 CB E8 98 00 E8 95 00 E8 92   ......).........
    0000002  00 4B 75 F4 E8 85 00 31 C9 31 D2 89 CE 8A 54 67   .Ku....1.1....Tg
    0000007  51 80 FA 20 72 0E 80 FA 7F 73 09 88 16 45 00 E8   Q.. r....s...E..
    0000008  8D 00 EB 08 C6 06 45 00 2E E8 83 00 59 41 3B 0E   ......E.....YA;.
    010000E  7D 00 72 D5 83 F9 10 72 02 EB 0E BB 10 00 29 CB   }.r....r......).
    010000B  E8 50 00 E8 4D 00 4B 75 F7 E8 4E 00 83 06 7F 00   .P..M.Ku..N.....
    0100000  10 E9 47 FF B4 3E 8B 1E 7B 00 CD 21 EB 29 BA 00   ..G..>..{..!.)..
    0100000  00 B4 09 CD 21 EB 20 BA 1D 00 B4 09 CD 21 BA 81   ....!. ......!..
    0100001  00 B4 09 CD 21 EB 10 BA 31 00 B4 09 CD 21 BA 81   ....!...1....!..
    0100001  00 B4 09 CD 21 EB 00 B8 00 4C CD 21 BA 62 00 E8   ....!....L.!.b..
    0100008  24 00 C3 BA 65 00 E8 1D 00 C3 BA 47 00 E8 16 00   $...e......G....
    0100000  C3 BA 4A 00 E8 0F 00 C3 BA 4F 00 E8 08 00 C3 BA   ..J......O......
    010000A  45 00 E8 01 00 C3 B4 09 CD 21 C3 31 FF C1 C2 04   E........!.1....
    0100004  89 D6 83 E6 0F 8A 44 52 88 45 4A 47 49 75 EE C3   ......DR.EJGIu..
    


Since I set "di" register to data segment, I change the "stosw" a litte bit:
Code:
      @@:
        add     ax, ('0'-6)+('0'-6) shl 8
        mov     [di], ax
        add     di,2   
    


If I cannot make it work, then I will just leave it as it. Thank you.
Post 27 Jan 2023, 12:46
View user's profile Send private message Visit poster's website Reply with quote
ProMiNick



Joined: 24 Mar 2012
Posts: 806
Location: Russian Federation, Sochi
ProMiNick 27 Jan 2023, 12:56
mov [di], cl - I force zero termination, maybe in DOS should be '$'. by the way thou already type '$' following _hexnum after 8 bytes. just clear mine termination.
Post 27 Jan 2023, 12:56
View user's profile Send private message Send e-mail Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1043
Location: Russia
macomics 27 Jan 2023, 14:49
FlierMate1 wrote:
Thanks to @macomics and @sinsi for their help in solving command-line arguments in DOS

Tomasz Grysztar determines the end of the parameter string by the carriage return symbol (CR = $0D)
SOURCE/DOS/FASM.ASM:113-130
Code:
get_params:
        mov     [input_file],0
        mov     [output_file],0
        mov     [symbols_file],0
        mov     [memory_setting],0
        mov     [passes_limit],100
        mov     [definitions_pointer],predefinitions
        push    ds
        mov     ds,[psp_segment]
        mov     esi,81h
        mov     edi,params
    find_param:
        lodsb
        cmp     al,20h
        je      find_param
        cmp     al,'-'
        je      option_param
        cmp     al,0Dh    
Post 27 Jan 2023, 14:49
View user's profile Send private message Reply with quote
FlierMate11



Joined: 13 Oct 2022
Posts: 94
FlierMate11 27 Jan 2023, 16:25
macomics wrote:
FlierMate1 wrote:
Thanks to @macomics and @sinsi for their help in solving command-line arguments in DOS

Tomasz Grysztar determines the end of the parameter string by the carriage return symbol (CR = $0D)
SOURCE/DOS/FASM.ASM:113-130


Luckily I did also in my HexdumpD.asm above, I notice it too from random search on the Internet.

It works for me, yes, I think CR needs to be detected.

Below is my code modified from yours. Taken from my hexdumpd.asm:
Must put null-character also at the back of filename so that DOS interrupt AH=3dh can open ASCIIZ filename. But also put "$" so that AH=9 can print it on screen. Rolling Eyes
Code:
        movzx   cx, [es:CMD_LENGTH]
        lea     di, [es:CMD_STRING]
        lea     si, [_filename]
        cmp     cx, 0
        jz      err0
again:
        mov     al, [es:di]
        cmp     al, ' '
        jnz     continue
        inc     di
        jmp     again
continue:
        cmp     al, 13
        jz      skip
        mov     [si], al
        inc     si
        inc     di
        loop    again
skip:
        xor     al, al
        mov     [si],al
        inc     si
        mov     al, '$'
        mov     [si], al     
    
Post 27 Jan 2023, 16:25
View user's profile Send private message Visit poster's website Reply with quote
FlierMate2



Joined: 21 Mar 2023
Posts: 39
FlierMate2 04 Apr 2023, 10:45
I have successfully convert 32-bit integer to hex values with the help of a cyber-pal.

This is the code:
Code:
;input: si - pointer to 32-bit integer
;output: _hexnum
ConvertLongHex:    Wink Nice code snippet by angch (Ang Chin Han)
   lea di, [_hexnum]
   mov bx, 2
.loop3:
   mov dx, word [si+2]
   mov cx, 4   ; 4 hexgit per 16 bit word
   push si
.loop1:
   rol dx, 4
   mov si, dx
   and  si, 0000fh
   mov al,[_digits+si]
   mov [di],al
   inc di
   dec cx
   jnz .loop1
   pop si
   sub si, 2 ; Next 16 bit word
   dec bx
   jnz .loop3
   ret              


And the data segment:
Code:
_offset   dd 0
_hexnum   rb 8
          db '$'
_digits   db '0123456789ABCDEF'      


My hexdump for DOS now fully operational with file larger than 64KB.


Description: v0.02 - fixed 32-bit hex conversion issue
Download
Filename: HEXDUMPD.ASM
Filesize: 5.42 KB
Downloaded: 275 Time(s)

Post 04 Apr 2023, 10:45
View user's profile Send private message Reply with quote
SeproMan



Joined: 11 Oct 2009
Posts: 70
Location: Belgium
SeproMan 10 Apr 2023, 20:11
I see that you have chosen to not use 32-bit registers in your ConvertLongHex subroutine. This decision of course is yours, and a good reason for doing so is to create an HEXDUMPD.EXE that can run on even the oldest of x86 architectures like 8086 or 80186. However, I did notice that your code is nonetheless using 32-bit operations and instructions that these old architectures don't support!

The MOVZX instruction was introduced with the 80386. You should replace 'movzx cx, [es:CMD_LENGTH]' by:

Code:
xor   cx, cx
mov   cl, [es:CMD_LENGTH]    


FASM will encode the 'add [_offset], 16' instruction so it performs a 32-bit addition because you used DD to define _offset. You should write this as:
Code:
add   word [_offset], 16
adc   word [_offset + 2], 0    


In ConvertLongHex and ConvertShortHex, the ROL instructions cannot rotate by an immediate count. You should use a count from the CL register. The following code snippets correct that problem. (I could not resist optimizing the code for speed Wink ):

Code:
; IN (si) OUT (di) MOD (al,bx,cl,si)
ConvertLongHex:
   mov  cl, 4                ; CONST
   mov  di, _hexnum + 8      ; Easier to fill from the end
.loop:
   mov  bl, [si]             ; SI points at current byte in a dword
   and  bx, 15
   dec  di
   mov  al, [_digits + bx]
   mov  [di], al
   mov  bl, [si]
   shr  bl, cl
   dec  di
   mov  al, [_digits + bx]
   mov  [di], al
   inc  si
   cmp  di, _hexnum
   jne  .loop
   ret

; IN (dl) OUT () MOD (ax,bx,cl)
ConvertShortHex:
   mov  cl, 4                ; CONST
   mov  bl, dl
   and  bx, 15
   mov  ah, [_digits + bx]
   mov  bl, dl
   shr  bl, cl
   mov  al, [_digits + bx]
   mov  [_hexval], ax
   ret    

_________________
Real Address Mode.
Post 10 Apr 2023, 20:11
View user's profile Send private message Reply with quote
FlierMate2



Joined: 21 Mar 2023
Posts: 39
FlierMate2 11 Apr 2023, 07:50
SeproMan wrote:
I see that you have chosen to not use 32-bit registers in your ConvertLongHex subroutine. This decision of course is yours, and a good reason for doing so is to create an HEXDUMPD.EXE that can run on even the oldest of x86 architectures like 8086 or 80186. However, I did notice that your code is nonetheless using 32-bit operations and instructions that these old architectures don't support!

The MOVZX instruction was introduced with the 80386. You should replace 'movzx cx, [es:CMD_LENGTH]' by:

Code:
xor   cx, cx
mov   cl, [es:CMD_LENGTH]    



Good eye! Thanks for your correction, this is a serious defect in my previous release of Hexdump for DOS, but fortunately I didn't promote it on DOS forum as it is not a real DOS program then.

I fixed it just now.

Quote:
...the ROL instructions cannot rotate by an immediate count.


From what I check, ROL with immediate value as argument is allowed starting from 80186.

For example,
Code:
 66 c1 c2 04             rol    dx,0x4    


As for your hex conversion routine, I will keep it for future reference (and it also serves as reference for other forum members here), I wish you posted a little earlier before I found the solution. Embarassed
Thank you once again!
Post 11 Apr 2023, 07:50
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1043
Location: Russia
macomics 11 Apr 2023, 09:50
Here is another option, but now using xlat
Code:
; IN (si) OUT (di) MOD (al,bx,cl,si)
ConvertLongHex:
   mov  cl, 4                ; CONST
   mov  di, _hexnum + 8      ; Easier to fill from the end
   mov  bx, _digits
 .loop:
   lods byte [si]                 ; SI points at current byte in a dword
   mov  ah, al
   and  al, 15
   shr  ah, cl
   dec  di
   xlat byte [bx]
   mov  [di], al
   dec  di
   mov  al, ah
   xlat byte [bx]
   mov  [di], al
   cmp  di, _hexnum
   jne  .loop
   ret

; IN (dl) OUT () MOD (ax,bx,cl)
ConvertShortHex:
   mov  cl, 4                ; CONST
   mov  bx, _digits
   mov  al, dl
   and  al, 15
   shr  dl, cl
   xlat byte [bx]
   xchg al, ah
   xlat byte [bx]
   mov  [_hexval], ax
   ret    
Post 11 Apr 2023, 09:50
View user's profile Send private message Reply with quote
FlierMate2



Joined: 21 Mar 2023
Posts: 39
FlierMate2 14 Apr 2023, 07:33
Sorry for multiple version of HEXDUMPD.ASM, this latest 0.03 version is uploaded with patches suggested by SeproMan, basically the:

Code:
xor   cx, cx
mov   cl, [es:CMD_LENGTH]     


...and...

Code:
add   word [_offset], 16
adc   word [_offset + 2], 0        


Thanks SeproMan!


Description: v0.03- contains patches by SeproMan
Download
Filename: HEXDUMPD.ASM
Filesize: 5.58 KB
Downloaded: 278 Time(s)

Post 14 Apr 2023, 07:33
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 20460
Location: In your JS exploiting you and your system
revolution 14 Apr 2023, 07:44
I hope you aren't conflating DOS and 8086 instructions.

You can use DOS with 32-bit instructions. DOS can run on 32-bit machines. It can also run on 64-bit machines. Just that it runs in real mode. That doesn't limit the instructions to only 8086, or 16-bit. It does make using 64-bit registers tricky because you need to switch modes, but otherwise unless you really have a very very old 80[1|2]86 machine then 32-bit code will run fine.
Post 14 Apr 2023, 07:44
View user's profile Send private message Visit poster's website Reply with quote
FlierMate2



Joined: 21 Mar 2023
Posts: 39
FlierMate2 14 Apr 2023, 08:01
revolution wrote:
I hope you aren't conflating DOS and 8086 instructions.

You can use DOS with 32-bit instructions. DOS can run on 32-bit machines. It can also run on 64-bit machines. Just that it runs in real mode. That doesn't limit the instructions to only 8086, or 16-bit. It does make using 64-bit registers tricky because you need to switch modes, but otherwise unless you really have a very very old 80[1|2]86 machine then 32-bit code will run fine.


Thank you for the timely reminder, I almost confused between DOS and 8086 instructions.
However, I still believe a small number of people are still using ancient machine to run DOS, then this HEXDUMPD.EXE might be for them. But I heard DOS users mainly use DEBUG.EXE to perform hexdump....

revolution wrote:
But one thing is for sure, you don't need to use two registers if you are running the code on a 32-bit capable machine.


Aha, now I fully understand what you mean. Laughing
Post 14 Apr 2023, 08:01
View user's profile Send private message Reply with quote
macomics



Joined: 26 Jan 2021
Posts: 1043
Location: Russia
macomics 14 Apr 2023, 09:19
FlierMate2 wrote:
But I heard DOS users mainly use DEBUG.EXE to perform hexdump....


Now there is TD.EXE and DEBUGX.COM


Last edited by macomics on 08 Mar 2024, 09:44; edited 2 times in total
Post 14 Apr 2023, 09:19
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page 1, 2  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-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.