News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Dword to ascii (dw2a, dwtoa, dw2str, Str$, ...)

Started by jj2007, April 01, 2024, 03:42:50 AM

Previous topic - Next topic

jj2007

@Sinsi: thanks :thumbsup:

Quote from: ahsat on April 01, 2024, 08:00:16 AMIntel must have really improved the speed of a divide on this processor.

The div ebx is indeed the bottleneck in your algo. I've tried to replace it with a mul 0CCCCCCCDh but with little success, speedwise. It's a pity because your algo is really very elegant and short :thumbsup:

ctAnyToAny:
  push edx ; save edx, or a digit
  xor edx, edx ; same as cdq but maybe a tick faster
  div ebx ; generate next digit in edx
  ; dec ecx ; decrement digit count
  test eax, eax ; anything left?
  .if !Zero? ; br if done
call ctAnyToAny ; generate next digit
  .endif
  mov al, @digits[edx] ; get the ascii value
  stosb ; save it
  pop edx ; restore edx, or get next digit
  ret

Btw you could drop the digit counter and instead check if anything is left in eax:
  div ebx ; generate next digit in edx
  ; dec ecx ; decrement digit count
  test eax, eax ; anything left?
  .if !Zero? ; br if done
call ctAnyToAny ; generate next digit
  .endif

Works fine and leaves one register intact. Speedwise there is no difference, it seems.

sinsi

Quote from: NoCforMe on April 01, 2024, 10:07:05 AMAs I wrote: except in a few cases, who cares how fast they are?. That's one of those few cases.
Or Explorer showing the details of 1000 files.
Or 7-zip showing a 20,000 file archive in flat view.
Anyway, I wouldn't class Excel (or Access) as "a few cases", seeing how well Office sells  :biggrin:

For me, a more useful algo would be to have thousand separators.

NoCforMe

Rather than continue this (tangential) discussion here, I've started a new topic in the Soap Box in this whole algorithm-speed thing.
Assembly language programming should be fun. That's why I do it.

NoCforMe

Quote from: sinsi on April 01, 2024, 11:02:59 AMFor me, a more useful algo would be to have thousand separators.
If you're talking about putting in, say, commas every 3 digits:

3,549,782

then here's my code that does that:
;====================================================================
; CommaNum (inputBuffer, outputBuffer)
;
; Number comma-formatting routine.
; On entry,
; inputBuffer has ASCII number string (zero-terminated)
;
; On exit,
; outputBuffer contains the comma-formatted number string.
;====================================================================

CommaNum PROC inputBuffer:DWORD, outputBuffer:DWORD
LOCAL digitMoveCount:DWORD, quotient:DWORD, remainder:DWORD

PUSH ESI
PUSH EDI

MOV EDI, outputBuffer ;Where to store our finished product.
MOV digitMoveCount, 3 ;Default # of digits to move/"triad".

; Inline strlen() here:
MOV EAX, inputBuffer
MOV ESI, EAX ;Set up for later moves.
XOR EDX, EDX ;Len. counter
sl10: CMP BYTE PTR [EAX + EDX], NULL
JE sl88
INC EDX
JMP sl10

sl88: MOV EAX, EDX ;EAX = # digits.
TEST EAX, EAX ;Test for zero length.
JZ done ;Cap off output buffer and exit.
XOR EDX, EDX
MOV ECX, 3
DIV ECX ;How many "triads"?
MOV quotient, EAX
MOV remainder, EDX

; If quotient = 0, use remainder as digit count for last "triad":
CMP quotient, 0
JNE @F
MOV EAX, remainder
MOV digitMoveCount, EAX
MOV quotient, 1 ;1 time through move loop.
JMP SHORT triads

; First see if there's a short "triad" at beginning:
@@: MOV ECX, remainder
JECXZ triads ;No remainder, so no short "triad".
REP MOVSB ;Yes, so move that many digits.
MOV AL, ','
STOSB ;Put in comma.

; Now we're just moving "triads" and putting in commas after them:
triads: MOV ECX, quotient
nloop: PUSH ECX
MOV ECX, digitMoveCount
REP MOVSB
POP ECX

; Do we put a comma in, or are we on the last "triad"?
CMP ECX, 1
JE nocom
MOV AL, ','
STOSB
nocom: LOOP nloop

; Cap off formatted # buffer:
done: MOV BYTE PTR [EDI], 0

exit99: POP EDI
POP ESI
RET

CommaNum ENDP
Assembly language programming should be fun. That's why I do it.

ahsat

Quote from: jj2007 on April 01, 2024, 10:24:11 AMIt's a pity because your algo is really very elegant and short
Thank you. I like elegant and short. I developed this algo circa 1978. We needed it for debugging on embedded systems. Replace the stosb with a print, and it printed one character at a time, usually on a tty.

This algo is also much more powerful, because it will do any base.

sinsi

Oh, I have code to do that. It does it while converting the number to ascii.
I was just wondering if there was a way of optimising it.

ahsat

Quote from: jj2007 on April 01, 2024, 10:24:11 AMBtw you could drop the digit counter and instead check if anything is left in eax:
You did not look at the code for Anybase.exe. There are two versions of the algorithm. One test eax, the other does a jecxz.

I now wonder if your speed tests were flawed. Base 10 should have use the algo that uses eax.

lingo

#22
Thank you ahsat, :thumbsup:

for positive integers less than 100,000,000 = 5F5E100h  I use:

; Int_to_string - Convert a small binary interger into an string
; IN:  RAX = binary integer
;       RCX = address of location to store string

align 16
db  90h,90h,90h
i2a       proc   
          mov    r9,  rcx
          mov    r8d, 10
          xor    ecx, ecx
          xor    edx, edx
@@:         
          div    r8               ; divide by the number-base
          shl    rcx, 8
          add    rdx, 30h
          xchg   dl,  cl
          test   eax, eax           
          jne    @b
          mov    [r9],rcx
          ret
i2a       endp
Quid sit futurum cras fuge quaerere.

ahsat


sinsi

xchg   dl,  clThat, mister, is the best instruction (for how many things it does) that I've ever seen.  :greenclp:

jj2007

Quote from: ahsat on April 01, 2024, 12:58:32 PMThere are two versions of the algorithm. One test eax, the other does a jecxz.

Apologies. I tested both versions, and there is no difference, speedwise. If you have a 32-bit version of the jecxz algo, please post it, so that I can incorporate it into the testbed. I also noted that your code produces 00000123 for dword=123, i.e. leading zeros.

ahsat

Quote from: NoCforMe on April 01, 2024, 10:10:12 AMI wish you the best of luck with your editor
I wish you both good luck. I am amazed at how poor text editors are today compared to what they use to be. The best text editor I have ever used was Brief. There is a fair start of al clone of Brief, called Grief, on Github. You guys should take a look if you haven't already.

A real text editor is like assembly language, it is not for the beginners.

ahsat

Quote from: jj2007 on April 01, 2024, 07:34:04 PMI also noted that your code produces 00000123 for dword=123
Not my code, but your implementation of my code. The original 64bit version that I posted only put leading zeros into hex and Sexagesimal, but no leading zeros with base 10. You would not use the jecxz version of the algo, unless you wanted the possibility of leading zeros.

The 32 bit version of Anybase.exe is working now. I have to clean it up but I will post it latter today.

Look closer this time, and you will see two versions of the algo, one with leading zeros and one without leading zeros.

NoCforMe

I remember using Brief, briefly back in the day. I thought it was OK.
The editor I really, really miss is MultiEdit, which up to XP would run under Windoze (no more on Win7). It did everything: regular expression search & replace, infinitely extensible through a sophisticated macro language (yes, JJ!), columnar text selection, so much more.

But then for years I plodded along using Notepad as an editor, until I wrote my own.

BTW, if you care to take a look at my editor, here's the latest version. If you do peek at it I'd be very interested in your take on it.

Assembly language programming should be fun. That's why I do it.

ahsat

#29
Quote from: jj2007 on April 01, 2024, 07:34:04 PMIf you have a 32-bit version of the jecxz algo
I just posted the 32 bit version of Anybase. It has both, and always had, both versions of the algo.

Sorry, I don't know how to directly link you to the post, but it is in the same message thread that I released the 64 bit version, the "Miscellaneous Projects " part of this forum.
EDIT: https://masm32.com/board/index.php?topic=11817.60