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 |
|
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.. |
|||
27 Jan 2023, 10:13 |
|
revolution 27 Jan 2023, 10:26
Not enough room for 8 characters.
FlierMate11 wrote:
|
|||
27 Jan 2023, 10:26 |
|
FlierMate11 27 Jan 2023, 11:11
revolution wrote: Not enough room for 8 characters. 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? |
|||
27 Jan 2023, 11:11 |
|
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...... |
|||
27 Jan 2023, 11:17 |
|
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
|
|||||||||||
27 Jan 2023, 11:33 |
|
revolution 27 Jan 2023, 11:45
FlierMate11 wrote: Do you know what's wrong? Or must use two registers for it? 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. |
|||
27 Jan 2023, 11:45 |
|
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 |
|||
27 Jan 2023, 12:12 |
|
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. |
|||
27 Jan 2023, 12:46 |
|
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.
|
|||
27 Jan 2023, 12:56 |
|
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 |
|||
27 Jan 2023, 14:49 |
|
FlierMate11 27 Jan 2023, 16:25
macomics wrote:
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. 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 |
|||
27 Jan 2023, 16:25 |
|
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: 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.
|
|||||||||||
04 Apr 2023, 10:45 |
|
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 ): 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. |
|||
10 Apr 2023, 20:11 |
|
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! 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. Thank you once again! |
|||
11 Apr 2023, 07:50 |
|
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 |
|||
11 Apr 2023, 09:50 |
|
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!
|
|||||||||||
14 Apr 2023, 07:33 |
|
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. |
|||
14 Apr 2023, 07:44 |
|
FlierMate2 14 Apr 2023, 08:01
revolution wrote: I hope you aren't conflating DOS and 8086 instructions. 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. |
|||
14 Apr 2023, 08:01 |
|
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 |
|||
14 Apr 2023, 09:19 |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.