News:

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

Main Menu

QWORD conversion function in MASM32 libraries?

Started by NoCforMe, July 12, 2022, 09:16:26 AM

Previous topic - Next topic

NoCforMe

Any chance there's a QWORD (to ASCII) converter somewhere in the MASM32 stuff? I looked in the help file but only found info on DWORD routines. Suppose I could write one myself, but why reinvent that particular wheel?
Assembly language programming should be fun. That's why I do it.

jj2007

http://masm32.com/board/index.php?topic=221.0

If speed is not an issue:
include \masm32\include\masm32rt.inc

.data
MyQ QWORD 12345678901234567890

.code
start:
  printf("The value of MyQ is %llu\n", MyQ)
  inkey "hit any key"
  exit

end start


If speed is important, try MasmBasic Str$(MyQ), it's a factor 3.6 faster than CRT printf().

NoCforMe

Quote from: jj2007 on July 12, 2022, 09:20:18 AM
http://masm32.com/board/index.php?topic=221.0

Regarding just that thread, I took a look at it, but I won't look any further. Why? Because the people who wrote that stuff do something that I really really really really HATE. Which is to use totally cryptic, un-understandable references to local variables like [esp+0*4] instead of just creating a goddamn readable LOCAL VARIABLE like everyone else does. ("Dedndave" is particularly guilty of this crime.) Why do this? It buys you absolutely nothing in terms of execution speed. All it does is make your code unintelligible. Sheesh.
Assembly language programming should be fun. That's why I do it.

NoCforMe

Quote from: jj2007 on July 12, 2022, 09:20:18 AM
If speed is not an issue:
include \masm32\include\masm32rt.inc

.data
MyQ QWORD 12345678901234567890

.code
start:
  printf("The value of MyQ is %llu\n", MyQ)
  inkey "hit any key"
  exit

end start


If speed is important, try MasmBasic Str$(MyQ), it's a factor 3.6 faster than CRT printf().

But I don't want printf(); I want something like wsprintf(), that formats to memory. Got anything like that? (Not MasmBasic, since I'm still not yet a user.)
Assembly language programming should be fun. That's why I do it.

jj2007

Quote from: NoCforMe on July 12, 2022, 09:35:53 AMtotally cryptic, un-understandable references to local variables like [esp+0*4]

I use this syntax over 250 times in my library, and don't feel guilty. Just get used to it :cool:

Simple example, coded tonight:
destx equ [esp-16]
desty equ [esp-12]
destw equ [esp-8]
desth equ [esp-4]
srcx equ [esp]
srcy equ [esp+4]
srcw equ [esp+8]
srch equ [esp+12]
xor ebx, ebx
push ebx ; callback data
push ebx ; callback
push ebx ; attributes
push UnitPixel ; unit=2
push edx ; src height
; fild stack
push eax ; src width
; fild stack
push ebx ; src y slot
push ebx ; src x slot
.DATA
align 16
cropdata dw 20, 20, -20, -20 ; x, y, w, h
.CODE
pmovsxwd xmm0, qword ptr cropdata
movups xmm1, oword ptr [esp]
PADDD xmm0, xmm1
movups oword ptr [esp], xmm0
fild stack[3*4] ; h
fild stack[2*4] ; w
deb 4, "A", ST(0), ST(1)
fld st ; copy of width
fmul [edi.GuiImageZOOM].gizX ; width*percentX
fiadd stack
deb 4, "srcX", ST(0)
nops 2
fistp stack ; new src X
fmul [edi.GuiImageZOOM].gizW ; width*percentW
fisubr stack[8] ; subtract from old width
fisub stack ; subtract left offset
fistp stack[8] ; new src width
fld st ; copy of height
fmul [edi.GuiImageZOOM].gizY ; height*percentY
fiadd stack[4]
fistp stack[4] ; new src Y
fmul [edi.GuiImageZOOM].gizH ; width*percentH
fisubr stack[12] ; subtract from old height
fisub stack[4] ; subtract top offset
fistp stack[12] ; new src height

NoCforMe

But why? Why on earth would you want to code something cryptically like that instead of using symbolic names like [insert name of deity here] intended? is it that much trouble to come up with names? How in the world do you look at that and know just what the hell [esp-8] refers to?

Like they say, smh ...
Assembly language programming should be fun. That's why I do it.

jj2007

Short answer: nobody forces me to use (for example) fild stack[3*4]...

NoCforMe

I did find what looks like a usable (and simple) routine in that thread you linked to, and it's from "dedndave". I've reformatted it to my liking here:


        .data

Q2Abuffer DB "01234567890123456789",0 ;20 ASCII digits

        .code

;====================================================================
; Convert 64-bit unsigned integer (QWORD) to ASCII decimal string
;
; On entry,
; EDX:EAX = QWORD value to convert
;
; Returns:
; EAX--> buffer containing numeric string
;====================================================================
Q2A PROC

PUSH EBX
PUSH EDI

STD ;No, not a venereal disease:
;set direction flag to go backwards.
MOV EDI, OFFSET Q2Abuffer + 18
MOV ECX, EDX
XCHG EAX, ESI
MOV EBX, 100 ;Load with divisor.

qloop: XOR EDX, EDX
XCHG EAX, ECX
DIV EBX
XCHG EAX, ECX
XCHG EAX, ESI
DIV EBX
XCHG EAX, ESI
XCHG EAX, EDX
AAM
XCHG AL, AH ;Swap bytes.
OR AX, 3030h ;Convert to ASCII.
STOSW ;Store 2 digits.
MOV EAX, ECX
OR EAX, ESI
JNZ qloop

ADD EDI, 2
CLD ;Be sure to clear direction flag!
CMP BYTE PTR [EDI], '0' ;Leading zero?
JNE exit99 ;  No, done.

INC EDI ;  Yep, increment past it.
exit99: MOV EAX, EDI ;Return with pointer to buffer.
POP EDI
POP EBX
RET

Q2A ENDP


Haven't tested it out yet, but I'm sure it'll do nicely.
Assembly language programming should be fun. That's why I do it.

hutch--

 :biggrin:

Everybody has a theory, I get to see code that is regularly unintelligible, its the name of the game. I am an addict of clarity but you don't get to see it all that much.

jj2007

Quote from: NoCforMe on July 12, 2022, 10:51:10 AMHaven't tested it out yet, but I'm sure it'll do nicely.

Not bad indeed, but you have two very slow DIV instructions in your code...

MyQ=12345678901234567890
2547 ms for Q2A
1264 ms for Str$()


MOV EDI, OFFSET Q2Abuffer + 18

If that line was my code, it would be
mov edi, offset Q2aBuffer+18

- ALL CAPS would drive me crazy
- a tab between mov and edi? No thanks, my eyes don't like jumping around
- Q2Abuffer looks like an inconsistent half camel case; Q2aBuffer is much more readible
- I don't need spaces around + and minus signs, they distract

As you can see, it's all a question of taste - as Hutch writes, "Everybody has a theory" ;-)

NoCforMe

Quote from: jj2007 on July 12, 2022, 05:11:57 PM
Quote from: NoCforMe on July 12, 2022, 10:51:10 AMHaven't tested it out yet, but I'm sure it'll do nicely.

Not bad indeed, but you have two very slow DIV instructions in your code...

Don't care. Speed matters not here. It's just used for some end-of-run reporting. Rather have small, simple code here.

BTW, regarding program formatting, I realize this is a religious issue ...
Assembly language programming should be fun. That's why I do it.

jj2007

Quote from: NoCforMe on July 12, 2022, 06:11:30 PMBTW, regarding program formatting, I realize this is a religious issue ...

Amen :tongue:

Vortex

Hello,

Anyone who tried crt_sprintf with %I64u ? That function does not seem to support 64-bit integers.

jj2007

Same as %llu in reply #1, Erol:

include \masm32\include\masm32rt.inc

.data
MyQ QWORD 12345678901234567890
buffer db 80 dup(?)

.code
start:
  cls
  invoke crt_sprintf, addr buffer, chr$("A: The value of MyQ is %I64u", 13, 10), MyQ
  printf("B: The value of MyQ is %I64u\n", MyQ)
  inkey addr buffer
  exit

end start

Vortex

Hi Jochen,

Thanks, the code below works fine. The specifier %I64u works with wsprintf too.

include \masm32\include\masm32rt.inc

.data

x       dq 12345678901234567890
f1      db '%I64u',0

.data?

buffer  db 128 dup(?)

.code

start:

    invoke  crt_sprintf,\
            ADDR buffer,ADDR f1,x
           
    invoke  StdOut,ADDR buffer

    invoke  ExitProcess,0

END start