News:

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

Main Menu

qword to ascii conversion

Started by allynm, June 06, 2012, 02:36:32 AM

Previous topic - Next topic

Antariy

Quote from: dedndave on June 10, 2012, 09:48:46 AM
i do this myself - but not for "reusable" functions - only for internal functions

I suppose this is an internal function as well and thus does not follow "normal" ABI (parameters passing, regs preservation, the way of returning value).

Antariy

Quote from: dedndave on June 10, 2012, 09:48:46 AM
in my ling long kai fang routine, i return
EAX = status
ECX = decimal string length
EDX = buffer address
the ECX and EDX values are intended to be convenient for the (assembly language) caller
however, they are not required to use the function
so, a C-callable OBJ could be made and linked with a C program

Hm... if you will return status and string length in one DWORD (to say status shl 8 or length), and address in another, it is possible to grab both returned values in C(++) code - just declare the function as returning LARGE_INTEGER or ULONGLONG (__int64) - this type of return assumes value to be returned in EDX:EAX and thus could be normally accessed in HLL code :biggrin:

KeepingRealBusy

Dave,

I put JJ's value in my code (just replaced my max unsigned value) and it correctly converted it. I did not use JJ's fix yet. Maybe his fix does not actually create the correct constant?

I am currently using MASM 8.0 since I want to see ALL generated code and MASM 9.0 does not support the -Sg option.

Still looking.

Dave.

dedndave

the listing shows the right stuff
that doesn't mean that's what's in the EXE, though   :P
00000000 .data
00000000 Src QWORD 1234567890123456
   000462D53C8ABAC0
00000008  00000064 [ Dest db 100 dup(?)
    00
   ]

    ALIGN                   QWORD
;    qHugeWork               QWORD 0
00000070     q16BillionBillion       QWORD 16000000000000000000
   DE0B6B3A76400000
;    q8BillionBillion        QWORD 8*1000000000*1000000000
;    q4BillionBillion        QWORD 4*1000000000*1000000000
;    q2BillionBillion        QWORD 2*1000000000*1000000000
;    q1BillionBillion        QWORD 1*1000000000*1000000000
    ALIGN                   DWORD
00000078 3B9ACA00     dHugeBillion            DWORD 1000000000
0000007C 00000000     dHugeBillions           DWORD 0
00000080 00000000     dTop                    DWORD 0
    ALIGN                   WORD
00000084 30 30 30 31 30     cbFirstTwo              BYTE "00","01","02","03","04","05","06","07","08","09"
   32 30 33 30 34
   30 35 30 36 30
   37 30 38 30 39
00000098  31 30 31 31 31                             BYTE "10","11","12","13","14","15","16","17","18"
   32 31 33 31 34
   31 35 31 36 31
   37 31 38

dedndave

Quote from: Antariy on June 10, 2012, 10:03:50 AMHm... if you will return status and string length in one DWORD (to say status shl 8 or length), and address in another, it is possible to grab both returned values in C(++) code - just declare the function as returning LARGE_INTEGER or ULONGLONG (__int64) - this type of return assumes value to be returned in EDX:EAX and thus could be normally accessed in HLL code :biggrin:

my LLKF routines handle bignums
the string length may be larger than 1 Mb   :biggrin:
and - the string length isn't needed to use the function
for C - all you need to know is success/fail, really
the output string is left-justified in the buffer, so they know the address
besides, who cares about those C guys, anyways - lol
if they want the string length, they can suck an egg and measure it

KeepingRealBusy

Dave,

My code seems to handle the conversion correctly (using MASM 8.0). I will use JJ's fix and see what I get. Very strange!

Dave.

KeepingRealBusy

Dave,

I tried with JJ's fix, worked fine. At least the second time. The first time I found that I had the incorrect number of zeros in dHugeBillion (too few). Fixed that and all is well?????

Dave.

dedndave

#37
Alex,
if i wanted to make a C-callable version, i could return the string length in EAX
then i could use SetLastError to reflect any error code if the string length is 0
for assembler, this would slow us down a little
i prefered to return the error code in EAX

Dave,
i have attached the program i put together
maybe you can spot where i went wrong
it only has the unsigned routine - i didn't get as far as testing the signed version

EDIT: attachment removed

KeepingRealBusy

Dave,

You have to fix ALL of the qxxBillionBillion constants, you only fixed the q16BillionBillion.

Dave.

dedndave

 :P

ok - they don't appear to be referenced in the unsigned routine

ahhh - that seems to fix it - my fault, Dave   :redface:

Antariy

Quote from: dedndave on June 10, 2012, 10:33:11 AM
the string length may be larger than 1 Mb   :biggrin:

Then you obviously should return the string length in EDX to avoid huge performance losses on (l)strlen algo :biggrin:
It is Windows C standard: LARGE_INTEGER/LONGLONG returned value is in EDX:EAX and you can easily access it in HLL as 2 DWORDs with no performance loss.

dedndave

lol
here is a little demo
this routine can handle some big numbers
signed or unsigned - mode selectable
1234567890123456
15001234558140725952
57896044618658097711785492504343953926634992332820282019728792003956564819968
-57896044618658097711785492504343953926634992332820282019728792003956564819968

let's see you return that in EDX:EAX   :P

KeepingRealBusy

Quote from: dedndave on June 10, 2012, 11:01:52 AM
:P

ok - they don't appear to be referenced in the unsigned routine

ahhh - that seems to fix it - my fault, Dave   :redface:

Dave,

They aren't, directly. The correction loop in UBTD walks through 6 QWORDS and corrects the input value to some value less than or equal to 1BillionBillion so I can do a divide. If I divide a max QWORD by a billion, I get an overflow with the remainder.

Dave.

Antariy

Quote from: dedndave on June 10, 2012, 11:14:38 AM
let's see you return that in EDX:EAX   :P

Read my post carefully.

EDX - is the output string length.
EAX - is the status.

No number itself is returned in regs :P :biggrin:

KeepingRealBusy

JJ,

I have updated the .zip with corrections found by you (assembly errors with MASM 6.15), and by me (not forcing a null terminator in the output string). I replaced the original .zip file.

Dave