The MASM Forum

General => The Campus => Topic started by: jimg on February 25, 2019, 05:18:35 AM

Title: wsprintf
Post by: jimg on February 25, 2019, 05:18:35 AM
When using wsprintf in 32 bit, is there any difference between  %ld and %d?
I have tried every combination I could think of and they all seem to work properly.
The documentation, however, seems to make a distinction between int and long.
Aren't they both 32 bits in 32bit masm?

As an additional question, does this change in 64bit?
Title: Re: wsprintf
Post by: jj2007 on February 25, 2019, 08:28:23 AM
Are you sure it's %ld, not %lld? I did a quick test, and it looks as if %ld == %d:

include \Masm32\MasmBasic\Res\JBasic.inc   ; ## builds in 32- or 64-bit mode with UAsm, ML, AsmC ##
Init           ; OPT_64 0      ; put 0 for 32 bit, 1 for 64 bit assembly
  PrintLine Chr$("This program was assembled with ", @AsmUsed$(1), " in ", jbit$, "-bit format.")
  .data
  longvar       QWORD 1234567890123456789
  intvar        DWORD 1234567890
  .code
  jinvoke crt_printf, Chr$("Test int  d:   %d", 13, 10), intvar
  jinvoke crt_printf, Chr$("Test int  ld:  %ld", 13, 10), intvar
  jinvoke crt_printf, Chr$("Test int  lld: %lld", 13, 10), intvar
  jinvoke crt_printf, Chr$("Test long d:   %d", 13, 10), longvar
  jinvoke crt_printf, Chr$("Test long ld:  %ld", 13, 10), longvar
  jinvoke crt_printf, Chr$("Test long lld: %lld", 13, 10), longvar
  Inkey "-- hit any key --"
EndOfCode


This program was assembled with UAsm64 in 32-bit format.
Test int  d:   1234567890
Test int  ld:  1234567890
Test int  lld: 9150716309725905618
Test long d:   2112454933
Test long ld:  2112454933
Test long lld: 1234567890123456789

This program was assembled with UAsm64 in 64-bit format.
Test int  d:   1234567890
Test int  ld:  1234567890
Test int  lld: 1234567890
Test long d:   2112454933
Test long ld:  2112454933
Test long lld: 1234567890123456789
Title: Re: wsprintf
Post by: jimg on February 25, 2019, 10:37:49 AM
I've never used %lld , it's not documented as a type in wsprintf.  Even in the latest Microsoft online documentation.

Yes, I did the same tests %d vs %ld vs %li and they all came out the same.  I've always used %li for some reason.  My initial reading of wsprintf led me to erroneously think int, in this context, was a 16bit integer,  short int was 8 bits, and long was 32 bits.   Why else would they exist?  Must be some leftover from the 16bit world.
Title: Re: wsprintf
Post by: jj2007 on February 25, 2019, 11:16:54 AM
Quote from: jimg on February 25, 2019, 10:37:49 AM
I've never used %lld , it's not documented as a type in wsprintf.  Even in the latest Microsoft online documentation.

Maybe. But it's the only one that works correctly with a QWORD, see above...
Title: Re: wsprintf
Post by: jimg on February 25, 2019, 11:30:48 AM
Just glancing at your code, I assumed that crt_printf called the c runtime print function.  A whole different animal than wsprintf.
Title: Re: wsprintf
Post by: aw27 on February 25, 2019, 04:57:18 PM
"ll" is fully documented and means long long. In general can be replaced with I64 (which is a Microsoft specific extension).
Title: Re: wsprintf
Post by: jimg on February 25, 2019, 05:16:15 PM
I never said it didn't exist at all, I said it doesn't exist in wsprintf documentation.   If you try using %lld in a format, wsprintf will print out "ld".
Title: Re: wsprintf
Post by: aw27 on February 25, 2019, 05:39:09 PM
Try %I64d.
Title: Re: wsprintf
Post by: TimoVJL on February 25, 2019, 07:35:13 PM
http://www.masmforum.com/board/index.php?PHPSESSID=8d46cd4ecb1688be429ab49694ec53e6&topic=14442.0
QuoteMichaelW:
According to this, "Starting with Windows XP, wsprintf and wvsprintf support the I64|I modifiers."
That information was removed later ?
Title: Re: wsprintf
Post by: jj2007 on February 25, 2019, 07:35:41 PM
Quote from: jimg on February 25, 2019, 11:30:48 AMA whole different animal than wsprintf.

I thought they belonged to the same family :(

  jinvoke crt_wsprintf, addr buffer, Chr$("Test long I64: %I64d", 13, 10), longvar
  jinvoke crt_printf, addr buffer


This program was assembled with ml64 in 64-bit format.
Test int  d:   1234567890
Test int  ld:  1234567890
Test int  lld: ld
Test long d:   2112454933
Test long ld:  2112454933
Test long lld: ld
Test long I64: 1234567890123456789


What a mess: different format codes for printf vs wsprintf :bgrin:

In short, for long:
printf knows %lld but works with I64d%, too
wsprintf needs %I64d
Title: Re: wsprintf
Post by: TimoVJL on February 25, 2019, 08:01:20 PM
wsprintfA/wsprintfW (https://docs.microsoft.com/fi-fi/windows/desktop/api/winuser/nf-winuser-wsprintfa) are from user32.dll.
printf family is from CRT.
ntdll.dll have some sprintf routines.
Title: Re: wsprintf
Post by: jimg on February 26, 2019, 03:22:28 AM
Thank you AW.  Interesting to know, but would be much better if it was documented.  Any documentation on I64/ll only applies to routines in the c runtime.