Author Topic: Notes about ML64 and h2incX includes and libraries  (Read 2628 times)

HSE

  • Member
  • *****
  • Posts: 1741
  • <AMD>< 7-32>
Notes about ML64 and h2incX includes and libraries
« on: April 28, 2021, 11:57:55 PM »
Hi All !

Building Hutch's examples using the Biterider's includes work well (and slow), with some little modifications :biggrin:.

This allow to make all functions Prototyped. And that is interesting to test an invoke macro that understand some kind of PROTO, wich could be necesary for some third party libraries.

  • 1 - You can't use "code" name.

Must be replaced ("_code" in this case):
[/list]
Code: [Select]
      DEBUGHOOKINFO struct
          idThread DWORD ?
          idThreadInstaller DWORD ?
          lParam LPARAM ?
          wParam WPARAM ?
          _code SDWORD ?
        DEBUGHOOKINFO ends
in winuser.inc
 
NMHDR.code is used, then must be corrected.

  • 2 - Twinning typedef:

Code: [Select]
    CONTEXT struct
      ···
    CONTEXT ends
 ;   _CONTEXT typedef CONTEXT ; anulado
    PCONTEXT typedef ptr CONTEXT

  • 3 - Problem with repeated element. Apparently can be commented or erased without problems:
   
Code: [Select]
           struct
              DUMMYRECORDNAME_??45 record friendlyNameFromEdid_??45:1, friendlyNameForced_??45:1, edidIdsValid_??45:1, reserved_??45:29
              ;DUMMYRECORDNAME_??45 <>
            ends

And an special problem with a 128 bit record (in winnt.inc):
Code: [Select]
      struct HeaderX64
          HeaderX64_??35 record Depth_??35:16, Sequence_??35:48;
          HeaderX64_??35_ record Reserved_??35:4, NextEntry_??35:60
          ;HeaderX64_??35 <>;anulado
        ends

  • 4 -  Some "C" macros remain after translation:
Code: [Select]
  _crt_va_arg macro ap, t
      exitm <((sizeof(t) > sizeof(__int64) or (sizeof(t) and (sizeof(t) - 1)) != 0) ? * * (t * *) ((ap + sizeof(__int64)) - sizeof(__int64)) : * (t *) ((ap + sizeof(__int64)) - sizeof(__int64)))>
    endm
replaced because doesn't matter in assembly
Code: [Select]
      exitm <t ptr ((ap + sizeof(__int64)) - sizeof(__int64))>
in vadefs.inc
  • 5 - I don't found what library require this:
Code: [Select]
  IEnumUnknown_Next_Proxy proto WIN_STD_CALL_CONV :ptr IEnumUnknown, :ULONG, :ptr ptr IUnknown, :ptr ULONG
  IEnumUnknown_Next_Stub proto WIN_STD_CALL_CONV :ptr IEnumUnknown, :ULONG, :ptr ptr IUnknown, :ptr ULONG
  IEnumString_Next_Proxy proto WIN_STD_CALL_CONV :ptr IEnumString, :ULONG, :ptr LPOLESTR, :ptr ULONG
  IEnumString_Next_Stub proto WIN_STD_CALL_CONV :ptr IEnumString, :ULONG, :ptr LPOLESTR, :ptr ULONG
  ISequentialStream_Read_Proxy proto WIN_STD_CALL_CONV :ptr ISequentialStream, :ptr, :ULONG, :ptr ULONG
  ISequentialStream_Read_Stub proto WIN_STD_CALL_CONV :ptr ISequentialStream, :ptr byte, :ULONG, :ptr ULONG
  ISequentialStream_Write_Proxy proto WIN_STD_CALL_CONV :ptr ISequentialStream, :ptr, :ULONG, :ptr ULONG
  ISequentialStream_Write_Stub proto WIN_STD_CALL_CONV :ptr ISequentialStream, :ptr byte, :ULONG, :ptr ULONG
  IStream_Seek_Proxy proto WIN_STD_CALL_CONV :ptr IStream, :LARGE_INTEGER, :DWORD, :ptr ULARGE_INTEGER
  IStream_Seek_Stub proto WIN_STD_CALL_CONV :ptr IStream, :LARGE_INTEGER, :DWORD, :ptr ULARGE_INTEGER
  IStream_CopyTo_Proxy proto WIN_STD_CALL_CONV :ptr IStream, :ptr IStream, :ULARGE_INTEGER, :ptr ULARGE_INTEGER, :ptr ULARGE_INTEGER
  IStream_CopyTo_Stub proto WIN_STD_CALL_CONV :ptr IStream, :ptr IStream, :ULARGE_INTEGER, :ptr ULARGE_INTEGER, :ptr ULARGE_INTEGER

Polink can't find the libraries. I don't know why there is an error if commenting them is Ok.
  • 6 - TARGET_BITNESS is used.
Clean solution is replace by _WIN64, but at this stage I declared it.
Code: [Select]
ifndef _WIN64                                         ;"type(near)" returns in 16-bit 0FF02h,
    if type(near) eq 0ff08h   ;64-bit enabled?          ;in 32-bit 0FF04h and in 64-bit 0FF08h.
      _WIN64 equ 1
      TARGET_BITNESS = 64
    elseif type(near) eq 0ff04h
      TARGET_BITNESS = 32
    endif
  endif

    Still testing examples, but look good.

    Regards, HSE.

    Biterider

    • Member
    • ****
    • Posts: 722
    • ObjAsm Developer
      • ObjAsm
    Re: Notes about ML64 and h2incX includes and libraries
    « Reply #1 on: April 29, 2021, 05:46:06 AM »
    Hi HSE
    Thanks for sharing your findings.
    Did you create some kind of test platform where you found this issues? Can you share it?
    I mainly tested the code with UASM. It may be possible that ML has some incompatibilities and performance issues, but we can work them out.

    Point 1: does not seem to be a problem for UASM
    Point 2: the WIN header files define it that way. There are cases where the underscore prepended name are referenced.
    Point 3: it is not a repetition. First it is defined and then it referenced. Maybe there are better ways to do it, but keep in mind that the translation is a single pass process
    Point 4: known problem. C macros are not translated since there is not simple way to do it without a full-featured C compiler. The macro is left in its original form as reference
    Point 5: I don't know
    Point 6: as you probably know, it is designed the other way around, but if you want to use the include files in this way, it should be fine.

    h2incX is a complex program that deserves more attention.
    I'll look at it in the coming days.
    Please keep posting all your findings.
    At the beginning of the application code I wrote some notes about features and bugs.

    Biterider


    HSE

    • Member
    • *****
    • Posts: 1741
    • <AMD>< 7-32>
    Re: Notes about ML64 and h2incX includes and libraries
    « Reply #2 on: April 29, 2021, 09:04:32 AM »
    Hi Biterider!

    I mainly tested the code with UASM. It may be possible that ML has some incompatibilities and performance issues, but we can work them out.

    Yes. ML64 have differences but for sure is posible to improve compatibility. I think there is not enough critical mass for 5 totally differents SDK.

    > Point 1: does not seem to be a problem for UASM
    No.

    >Point 2: the WIN header files define it that way. There are cases where the underscore prepended name are referenced.
    Yes. Headers are readed by compilers.

    >Point 3: it is not a repetition. First it is defined and then it referenced. Maybe there are better ways to do it, but keep in mind that the translation is a single pass process
     :biggrin: Sorry, I was thinking in a repetition, ML64 tell me that.

    >Point 4: known problem. C macros are not translated since there is not simple way to do it without a full-featured C compiler. The macro is left in its original form as reference
    Only one showed a problem in test. But remain more C macros with conditionals.

    >Point 5: I don't know
    It's a mistery

    >Point 6: as you probably know, it is designed the other way around, but if you want to use the include files in this way, it should be fine.
    Yes. A lot of posible ways.

    h2incX is a complex program that deserves more attention.
    I'll look at it in the coming days.
    Until now, some few manual modifications look enough to begin the analysis.

    Attached reference Hutch' example and modified includes.
    HSE

    LiaoMi

    • Member
    • ****
    • Posts: 922
    Re: Notes about ML64 and h2incX includes and libraries
    « Reply #3 on: April 29, 2021, 07:59:37 PM »
    Hi Biterider,

    there is one very interesting project in which we can read how it should work in theory.

    Quote
    Point 4: known problem. C macros are not translated since there is not simple way to do it without a full-featured C compiler. The macro is left in its original form as reference

    Rejuvenating C++ Programs through Demacrofication - https://stroustrup.com/icsm-2012-demacro.pdf
    Source Code - https://github.com/hiraditya/cpp2cxx

    Code: [Select]
    #include "header1.h"

    #define A 100

    #define _c(i) i
    #define _a(i) i*i

    #define CRYPTOPP_X86_ASM_AVAILABLE
    #define FXY(X,Y,Z) ((X) + (Y))
    #define fun() FXY(1,200,3)

    int i = fun();
    int super(int i)
    {

    #define INSIDE_FUN_SUPER(X,Y) X+100 + j

      //variable 'j' referenced in macro INSIDE_FUN_SUPER
      //the transformation has to be carefully placed after the declaration of 'int j'
      int j = 10;

      return INSIDE_FUN_SUPER(10000, 4000);
    }
    int l = FXY((i+i),super(10),100);



    #define proc(X,Y) {\
      X = FXY(X,Y,0);\
      }
    #define MSB(x) (((x) >> 24) & 0xffU)  /* most  significant byte */

    #include<iostream>

    int main()
    {
      int a1 = A;
      std::cout<<"\na1 = "<<a1;
     


    #define INSIDE_FUN(X) X+100

      int infun = INSIDE_FUN(105)+a1;

      int p = _c(100);
      int q = _a(100);

      std::cout<<"\np = "<<p;
      std::cout<<"\nq = "<<q;

      std::cout<<"\nl = "<<l;
      std::cout<<"\ninfun = "<<infun;
      std::cout<<"\nMSB(167816141) = "<<MSB(167816141);

      int lval = 0;
      proc(lval, 2);

      std::cout<<"\nlval = "<<lval<<"\n";
      return 0; 
    }

    Demacrofication for the macro
    Code: [Select]
    #include "header1.h"


    /** Demacrofication for the macro depth0 with unique identifier USE_depth0_examplecpp_3_9*/
    constexpr auto depth0 = 0;

    /** Demacrofication for the macro a with unique identifier USE_a_examplecpp_4_9*/
    constexpr auto a = 100;

    /** Demacrofication for the macro b with unique identifier USE_b_examplecpp_5_9*/
    constexpr auto b = 200;


    /** Demacrofication for the macro _c with unique identifier USE__c_examplecpp_7_9*/
    template <class _T1>
    auto _c(_T1 i) -> decltype(i)
    {
      return i;
    }

    /** Demacrofication for the macro _a with unique identifier USE__a_examplecpp_8_9*/
    template <class _T1>
    auto _a(_T1 i) -> decltype(i*i)
    {
      return i*i;
    }

    #define CRYPTOPP_X86_ASM_AVAILABLE

    /** Demacrofication for the macro FXY with unique identifier USE_FXY_examplecpp_11_9*/
    template <class _T1, class _T2, class _T3>
    auto FXY(_T1 X, _T2 Y, _T3 Z) -> decltype(((X) + (Y)))
    {
      return ((X) + (Y));
    }

    /** Demacrofication for the macro fun with unique identifier USE_fun_examplecpp_12_9*/

    auto fun() -> decltype(FXY(1,200,3))
    {
      return FXY(1,200,3);
    }

    int i = fun();
    int super(int i)
    {


      //variable 'j' referenced in macro INSIDE_FUN_SUPER
      //the transformation has to be carefully placed after the declaration of 'int j'
      int j = 10;


    /** Demacrofication for the macro INSIDE_FUN_SUPER with unique identifier USE_INSIDE_FUN_SUPER_examplecpp_18_9*/
    auto INSIDE_FUN_SUPER = [&j](decltype(10000) X, decltype( 4000) Y) { return X+100 + j; };
      return INSIDE_FUN_SUPER(10000, 4000);
    }
    int l = FXY((i+i),super(10),100);

    int aPtr[] = {1,2,3,4,5,6,7,8,9,10};
    int cPtr[] = {1,2,3,4,5,6,7,8,9,10};



    /** Demacrofication for the macro proc with unique identifier USE_proc_examplecpp_32_9*/
    template <class _T1, class _T2>
    void proc(_T1 && X, _T2 && Y)
    {
      FXY(X,Y,0);
      }


    /** Demacrofication for the macro MSB with unique identifier USE_MSB_examplecpp_35_9*/
    template <class _T1>
    auto MSB(_T1 x) -> decltype((((x) >> 24) & 0xffU)  /* most  significant byte */)
    {
      return (((x) >> 24) & 0xffU)  /* most  significant byte */;
    }


    /** Demacrofication for the macro SSB with unique identifier USE_SSB_examplecpp_36_9*/
    template <class _T1>
    auto SSB(_T1 x) -> decltype((((x) >> 16) & 0xffU)  /* second in significance */)
    {
      return (((x) >> 16) & 0xffU)  /* second in significance */;
    }


    /** Demacrofication for the macro TSB with unique identifier USE_TSB_examplecpp_37_9*/
    template <class _T1>
    auto TSB(_T1 x) -> decltype((((x) >>  8) & 0xffU)  /* third  in significance */)
    {
      return (((x) >>  8) & 0xffU)  /* third  in significance */;
    }


    /** Demacrofication for the macro LSB with unique identifier USE_LSB_examplecpp_38_9*/
    template <class _T1>
    auto LSB(_T1 x) -> decltype((((x)      ) & 0xffU)  /* least significant byte */)
    {
      return (((x)      ) & 0xffU)  /* least significant byte */;
    }


    #include<iostream>

    int main()
    {
      int a1 = a;
      int b1 = b;
      int c1 = 'c';
     
      //std::cout<<MSB(102400)<<"\n";
      //std::cout<<LSB(102400)<<"\n";
      //std::cout<<TSB(102400)<<"\n";
      //std::cout<<SSB(102400)<<"\n";
     
      int p = _c(100);
      int q = _a(100);

    /** Demacrofication for the macro INSIDE_FUN with unique identifier USE_INSIDE_FUN_examplecpp_55_9*/
    auto INSIDE_FUN = [](decltype(105) X) { return X+100; };
      int infun = INSIDE_FUN(105)+a1+b1+c1;
      //std::cout<<p<<"\t"<<q<<"\n"; 
      return 0; 
    }


    LiaoMi

    • Member
    • ****
    • Posts: 922
    Re: Notes about ML64 and h2incX includes and libraries
    « Reply #4 on: April 29, 2021, 08:44:13 PM »
    Hi Biterider!

    I mainly tested the code with UASM. It may be possible that ML has some incompatibilities and performance issues, but we can work them out.

    Yes. ML64 have differences but for sure is posible to improve compatibility. I think there is not enough critical mass for 5 totally differents SDK.

    > Point 1: does not seem to be a problem for UASM
    No.

    >Point 2: the WIN header files define it that way. There are cases where the underscore prepended name are referenced.
    Yes. Headers are readed by compilers.

    >Point 3: it is not a repetition. First it is defined and then it referenced. Maybe there are better ways to do it, but keep in mind that the translation is a single pass process
     :biggrin: Sorry, I was thinking in a repetition, ML64 tell me that.

    >Point 4: known problem. C macros are not translated since there is not simple way to do it without a full-featured C compiler. The macro is left in its original form as reference
    Only one showed a problem in test. But remain more C macros with conditionals.

    >Point 5: I don't know
    It's a mistery

    >Point 6: as you probably know, it is designed the other way around, but if you want to use the include files in this way, it should be fine.
    Yes. A lot of posible ways.

    h2incX is a complex program that deserves more attention.
    I'll look at it in the coming days.
    Until now, some few manual modifications look enough to begin the analysis.

    Attached reference Hutch' example and modified includes.
    HSE

    Hi HSE,

    you should take into account that Hutch does not use function prototypes, even if they are taken into account, they often do not coincide with, how the functions are called within a macro, means that the prototypes of the translator are different.  :icon_idea:

    Quote
     
    5 - I don't found what library require this:

    IEnumString_Next_Proxy proto WIN_STD_CALL_CONV :ptr IEnumString, :ULONG, :ptr LPOLESTR, :ptr ULONG
    Code: [Select]
    //+-------------------------------------------------------------------------
    //
    //  Microsoft Windows
    //  Copyright (C) Microsoft Corporation, 1994 - 1996.
    //
    //  File:       call_as.c
    //
    //  Contents:   [call_as] wrapper functions for COMMON\types.
    //+-------------------------------------------------------------------------
    //
    //  Function:   IEnumString_Next_Proxy
    //
    //  Synopsis:   Client-side [call_as] wrapper function for
    //              IEnumString::Next.  This wrapper function handles the
    //              case where pceltFetched is NULL.
    //
    //  Notes:      If pceltFetched != 0, then the number of elements
    //              fetched will be returned in *pceltFetched.  If an error
    //              occurs, then *pceltFetched is set to zero.
    //
    //--------------------------------------------------------------------------

    Windows Apps Win32 API Component Object Model (COM) Objidl.h IEnumString interface IEnumString::Next method
    https://docs.microsoft.com/en-us/windows/win32/api/objidl/nf-objidl-ienumstring-next
    https://docs.microsoft.com/en-us/windows/win32/midl/call-as

    Remarks
    The ability to map a function that cannot be called remotely to a remote function is particularly helpful in interfaces that have numerous parameter types that cannot be transmitted across the network. Rather than using many [represent_as] and [transmit_as] types, you can combine all the conversions using [call_as] routines. You supply the two [call_as] routines (client side and server side) to bind the routine between the application calls and the remote calls.

    The [call_as] attribute can be used for object interfaces. In this case, the interface definition can be used for local calls as well as remote calls because [call_as] allows an interface that can't be accessed remotely to be transparently mapped to a remote interface. The [call_as] attribute cannot be used with /osf mode.

    HSE

    • Member
    • *****
    • Posts: 1741
    • <AMD>< 7-32>
    Re: Notes about ML64 and h2incX includes and libraries
    « Reply #5 on: April 29, 2021, 09:39:33 PM »
    Hi LioMi!

    Rejuvenating C++ Programs through Demacrofication - https://stroustrup.com/icsm-2012-demacro.pdf

    First idea is to translate macros, not to erase them.

    At some point could be interesting to build an specific package, because macros  take time.

    you should take into account that Hutch does not use function prototypes, even if they are taken into account, they often do not coincide with, how the functions are called within a macro, means that the prototypes of the translator are different.  :icon_idea:
     
    ML64 don't use prototypes. Ideally all functions in 64 bits must be Unprototyped following x64 ABI. If that is followed, Hutch's invoke macro never will fail (except floating point number, but is very simple to correct that).
    With very little modifications of invoke macro you can make more easy programming (making automatic the promotion to follow x64 ABI) and to be capable to manage some other ideas (Prototyped functions are included in x64 ABI).

    docs.microsoft.com/en-us/windows/win32/api/objidl/nf-objidl-ienumstring-next

     :thumbsup: Apparently is used for UWP programs. Don't say in wich library that functions are. Perhaps are VS functions.

    Thanks, HSE.

    TouEnMasm

    • Member
    • *****
    • Posts: 1805
      • EditMasm
    Re: Notes about ML64 and h2incX includes and libraries
    « Reply #6 on: April 29, 2021, 10:37:58 PM »
    Quote
    ML64 don't use prototypes. Ideally all functions in 64 bits must be Unprototyped following x64 ABI
    ?????????????????????????????????????????
    ML64 can read protototypes and if it was said that prototypes had no use,c and c++ will not use them.
    This isn't a rule " 64 bits must be Unprototyped following x64 ABI".
    It's only true for ml64 because microsoft don't want to do it,perhaps it was two much expensive.
    Microsoft had designed ML64 to replace the inline assembler suppressed in Cand C++,NO MORE.
    Fa is a musical note to play with CL

    jj2007

    • Member
    • *****
    • Posts: 11550
    • Assembler is fun ;-)
      • MasmBasic
    Re: Notes about ML64 and h2incX includes and libraries
    « Reply #7 on: April 29, 2021, 10:42:49 PM »
    ML64 don't use prototypes. Ideally all functions in 64 bits must be Unprototyped following x64 ABI.

    I agree with Yves, that sounds strange. Knowing the type madness of the C/C++ fans, there must be a way to tell MASM which arguments are expected, and how many (my own macros do that already).

    LiaoMi

    • Member
    • ****
    • Posts: 922
    Re: Notes about ML64 and h2incX includes and libraries
    « Reply #8 on: April 29, 2021, 10:44:41 PM »
    you should take into account that Hutch does not use function prototypes, even if they are taken into account, they often do not coincide with, how the functions are called within a macro, means that the prototypes of the translator are different.  :icon_idea:
     
    ML64 don't use prototypes. Ideally all functions in 64 bits must be Unprototyped following x64 ABI. If that is followed, Hutch's invoke macro never will fail (except floating point number, but is very simple to correct that).
    With very little modifications of invoke macro you can make more easy programming (making automatic the promotion to follow x64 ABI) and to be capable to manage some other ideas (Prototyped functions are included in x64 ABI).

    Hi HSE,

    I meant that the data flow in the Hutch's technique differs from the data flow in the UASM according to the prototype method. The translator works well for UASM and should not be adapted for ml64, otherwise it will break all logic.

    Quote
    If that is followed, Hutch's invoke macro never will fail (except floating point number, but is very simple to correct that).
    :arrow_down:
    Code: [Select]
    C:\masm64\sdkrc100\um\wtypesbase.inc(85) : Error A2210: Syntax error: SHORT
     C:\masm64\sdkrc100\um\wtypesbase.inc(85): Included by
      C:\masm64\sdkrc100\um\combaseapi.inc(243): Included by
       C:\masm64\sdkrc100\um\objbase.inc(22): Included by
        C:\masm64\sdkrc100\um\ole2.inc(31): Included by
         C:\masm64\sdkrc100\um\ShlObj.inc(77): Included by
          mcalc.asm(33): Main line code
    mcalc.asm(245) : Error A2295: Invalid use of pointer operator
     REGISTER(109)[macros64.inc]: Macro called from
      procedure_call(19)[macros64.inc]: Macro called from
       ml_invoke(1)[macros64.inc]: Macro called from
        savefile(1)[macros64.inc]: Macro called from
         mcalc.asm(245): Main line code
    mcalc.asm(245) : Error A2295: Invalid use of pointer operator
     REGISTER(109)[macros64.inc]: Macro called from
      procedure_call(23)[macros64.inc]: Macro called from
       ml_invoke(1)[macros64.inc]: Macro called from
        savefile(1)[macros64.inc]: Macro called from
         mcalc.asm(245): Main line code
    mcalc.asm(252) : Error A2295: Invalid use of pointer operator
     REGISTER(109)[macros64.inc]: Macro called from
      procedure_call(19)[macros64.inc]: Macro called from
       ml_invoke(1)[macros64.inc]: Macro called from
        GetFontHandle(1)[macros64.inc]: Macro called from
         mcalc.asm(252): Main line code
    mcalc.asm(253) : Error A2295: Invalid use of pointer operator
     REGISTER(109)[macros64.inc]: Macro called from
      procedure_call(19)[macros64.inc]: Macro called from
       ml_invoke(1)[macros64.inc]: Macro called from
        GetFontHandle(1)[macros64.inc]: Macro called from
         mcalc.asm(253): Main line code
    mcalc.asm(254) : Error A2295: Invalid use of pointer operator
     REGISTER(109)[macros64.inc]: Macro called from
      procedure_call(19)[macros64.inc]: Macro called from
       ml_invoke(1)[macros64.inc]: Macro called from
        GetFontHandle(1)[macros64.inc]: Macro called from
         mcalc.asm(254): Main line code
    mcalc.asm(299) : Error A2048: Operands must be the same size: 8 - 4
    mcalc.asm(301) : Error A2048: Operands must be the same size: 4 - 8
    mcalc.asm(304) : Error A2048: Operands must be the same size: 8 - 4
    mcalc.asm(306) : Error A2048: Operands must be the same size: 4 - 8
    mcalc.asm(383) : Error A2160: INVOKE requires prototype for procedure
    mcalc.asm(443) : Error A2160: INVOKE requires prototype for procedure
    mcalc.asm(457) : Error A2160: INVOKE requires prototype for procedure
    mcalc.asm(507) : Error A2160: INVOKE requires prototype for procedure
    mcalc.asm(522) : Error A2160: INVOKE requires prototype for procedure
    mcalc.asm(605) : Error A2160: INVOKE requires prototype for procedure
    mcalc.asm(618) : Error A2160: INVOKE requires prototype for procedure
    mcalc.asm(628) : Error A2160: INVOKE requires prototype for procedure
    mcalc.asm(687) : Error A2145: INVOKE argument type mismatch: argument 4
    mcalc.asm(696) : Error A2160: INVOKE requires prototype for procedure
    mcalc.asm(697) : Error A2160: INVOKE requires prototype for procedure
    mcalc.asm(798) : Error A2145: INVOKE argument type mismatch: argument 3
    mcalc.asm(798) : Error A2048: Operands must be the same size: 4 - 8
    mcalc.asm(808) : Error A2102: Symbol not defined : CHARRANGE
    mcalc.asm(812) : Warning A4073: Size not specified, assuming: BYTE
    mcalc.asm(836) : Error A2295: Invalid use of pointer operator
     REGISTER(109)[macros64.inc]: Macro called from
      procedure_call(19)[macros64.inc]: Macro called from
       rv(1)[macros64.inc]: Macro called from
        mcalc.asm(836): Main line code
    mcalc.asm(842) : Error A2295: Invalid use of pointer operator
     REGISTER(109)[macros64.inc]: Macro called from
      procedure_call(19)[macros64.inc]: Macro called from
       rv(1)[macros64.inc]: Macro called from
        mcalc.asm(842): Main line code
    mcalc.asm(1013) : Error A2160: INVOKE requires prototype for procedure
     loadfile(1)[macros64.inc]: Macro called from
      mcalc.asm(1013): Main line code
    mcalc.asm(1033) : Error A2295: Invalid use of pointer operator
     REGISTER(109)[macros64.inc]: Macro called from
      procedure_call(19)[macros64.inc]: Macro called from
       ml_invoke(1)[macros64.inc]: Macro called from
        savefile(1)[macros64.inc]: Macro called from
         mcalc.asm(1033): Main line code
    mcalc.asm(1033) : Error A2295: Invalid use of pointer operator
     REGISTER(109)[macros64.inc]: Macro called from
      procedure_call(23)[macros64.inc]: Macro called from
       ml_invoke(1)[macros64.inc]: Macro called from
        savefile(1)[macros64.inc]: Macro called from
         mcalc.asm(1033): Main line code

    Hutch's technique x64:
    invoke SendMessage,hEdit,EM_SETMARGINS,EC_LEFTMARGIN or EC_RIGHTMARGIN,eax

    SendMessage function (winuser.h) - https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-sendmessage

    Code: [Select]
    LRESULT SendMessage(
      HWND   hWnd,
      UINT   Msg,
      WPARAM wParam,
      LPARAM lParam
    );

    What happens to WPARAM, LPARAM, and LRESULT when they travel between 32-bit and 64-bit windows? - https://devblogs.microsoft.com/oldnewthing/20110629-00/?p=10303 (Raymond Chen)
    Quote
    typedef UINT_PTR WPARAM;
    typedef LONG_PTR LPARAM;
    typedef LONG_PTR LRESULT;

     typedef __int3264 LONG_PTR;

    __int3264
    03/30/2020
    2 minutes to read
    An alias that is resolved to either:

    An __int32 in a 32-bit translation and execution environment, or
    An __int64 in a 64-bit translation and execution environment. For backward compatibility, it is 32-bit on the wire. The higher 4 bytes MUST be truncated on the sender side during marshaling and MUST be extended appropriately (signed or unsigned), as specified in [C706] section 14.2.5, on the receiving side during unmarshaling.

    HSE

    • Member
    • *****
    • Posts: 1741
    • <AMD>< 7-32>
    Re: Notes about ML64 and h2incX includes and libraries
    « Reply #9 on: April 30, 2021, 02:39:24 AM »
    Hi LioMi!

     :biggrin:  :biggrin: :biggrin:

    Code: [Select]
    Microsoft (R) Windows (R) Resource Compiler Version 10.0.10011.16384
    Copyright (C) Microsoft Corporation.  All rights reserved.

     Assembling: mcalc.asm
    Microsoft (R) Incremental Linker Version 14.00.24213.1
    Copyright (C) Microsoft Corporation.  All rights reserved.

     El volumen de la unidad C no tiene etiqueta.
     El número de serie del volumen es: 1000-D537

     Directorio de C:\masm32\examples64\mcalc

    28/04/2021  08:55            27.265 mcalc.asm
    28/04/2021  09:24                16 mcalc.bin
    29/04/2021  12:59            32.768 mcalc.exe
    11/10/2018  22:19               978 mcalc.inc
    29/04/2021  12:59            24.267 mcalc.obj
                   5 archivos         85.294 bytes
                   0 dirs  374.203.731.968 bytes libres
    Presione una tecla para continuar . . .

    This is about ML64 and Biterider's includes (they are in ObjAsm SDK), not about UASM logic. Anyway I don't see problems using modified includes with UASM, just that NMHDR.code is very used in ObjAsm examples (but is because I changed the name in the structure).


    I don't remember a problem with SHORT, perhaps is other translation.

    In Hutch2.zip there is a macros64.asm. I think is Hutch original, but with 4 forced expansions of reparg. You can make a diff with your macros64.asm

    If you have time, perhaps you can test the modifications to macros64.asm that are under study.

    « Last Edit: April 30, 2021, 03:40:53 AM by HSE »

    HSE

    • Member
    • *****
    • Posts: 1741
    • <AMD>< 7-32>
    Re: Notes about ML64 and h2incX includes and libraries
    « Reply #10 on: April 30, 2021, 03:36:53 AM »
    if it was said that prototypes had no use,c and c++ will not use them.
    I'm not talking about c and c++.

    This isn't a rule " 64 bits must be Unprototyped following x64 ABI".
    I think that rule exist in M$. Most 64 bit Win API apparently follow that rule. You can see how well work Hutch's masm64 SDK. 

    I agree with Yves, that sounds strange.
    :thumbsup:    Just is that way. :biggrin:

    Knowing the type madness of the C/C++ fans
    Compilers take care of that.

    there must be a way to tell MASM which arguments are expected, and how many (my own macros do that already).
    No. That is the idea: because we don't like compilers very much, macros have to take care of that.

    Biterider

    • Member
    • ****
    • Posts: 722
    • ObjAsm Developer
      • ObjAsm
    Re: Notes about ML64 and h2incX includes and libraries
    « Reply #11 on: April 30, 2021, 04:41:53 AM »
    Hi HSE
    I finally got Hutch2 running. I had to move things around and modify paths but finally (after 19 secs of compilation time) I got the exe.   :greenclp:
    I had to try several times as ML64 crashes with cryptic error messages or no error at all.  :sad:
    That it takes so long to compile such a short program is [...]

    At least I have something to work with  :thumbsup:

    Biterider


    jj2007

    • Member
    • *****
    • Posts: 11550
    • Assembler is fun ;-)
      • MasmBasic
    Re: Notes about ML64 and h2incX includes and libraries
    « Reply #12 on: April 30, 2021, 05:04:42 AM »
    ML64 crashes with cryptic error messages

    I see them frequently when I test my "dual" stuff with ML64. No problem, just try again.

    hutch--

    • Administrator
    • Member
    • ******
    • Posts: 8491
    • Mnemonic Driven API Grinder
      • The MASM32 SDK
    Re: Notes about ML64 and h2incX includes and libraries
    « Reply #13 on: April 30, 2021, 06:08:18 AM »
    Some of this makes me laugh, inflict left over prototyping onto 64 bit MASM and you turn it to crippleware. There are enough people who can produce a prototyping technique but its big, slow and clumsy. About the only thing it inherited from ML.EXE was the ancient pre-processor which made it possible to civilise it enough to be able to write working code with.

    While both John and nidud are producing assemblers that are morphing into C compilers, 64 bit MASM has no aspirations in that direction at all and the sheer simplicity of its prototyping made for a clean and easy construction method for a large near complete set.

    There is a solution for those who need prototyping, decent documentation and if anyone could be bothered, a post source scanner to test if code is written correctly but the best code scanner is the author and MASM makes no assumptions other that the author should write the code correctly.

    Now with h2incX, its assumptions make it a crippled piece of junk, the Microsoft C/C++ headers are deliberately produced in the most obscure method possible to prevent access to other tools and this includes assemblers. If you have ever bothered to run the full set of includes through a C compiler with a full listing, you will see that the C compiler strips all of the junk out of the headers and this was one of the many ways that you got a list of functions with the correct number of arguments.

    To compound this, the linker libraries do not include the byte count data that 32 bit STDCALL libraries contained. I see the pursuit of old technology for assemblers to have the 1990 format of prototypes as a fool's errand harking back to a simpler era where the Microsoft h2inc.exe actually worked.

    To get something like h2incX to work, you need to map the entire C header system to handle the repeated different equates and be able to track the paths taken by any particular version of the Microsoft headers. The construction of the 32 bit windows.inc was a horrendous task that over time was a massive amount of work and testing, that is why most copied its internals rater than doing their own work to produce all of the data.

    externdef __imp_SendMessageA:PPROC
    SendMessageA equ <__imp_SendMessageA>
      IFNDEF __UNICODE__
        SendMessage equ <__imp_SendMessageA>
      ENDIF

    externdef __imp_SendMessageW:PPROC
    SendMessageW equ <__imp_SendMessageW>
      IFDEF __UNICODE__
        SendMessage equ <__imp_SendMessageW>
      ENDIF

    This matches the linker libraries, pursuing 1990 prototypes is out of date junk with MASM in 64 bit.
    hutch at movsd dot com
    http://www.masm32.com    :biggrin:  :skrewy:

    HSE

    • Member
    • *****
    • Posts: 1741
    • <AMD>< 7-32>
    Re: Notes about ML64 and h2incX includes and libraries
    « Reply #14 on: April 30, 2021, 09:39:16 AM »
    Hi Biterider!

     :thumbsup:

    That it takes so long to compile such a short program is [...]

    Perhaps Lena know what happen with ML64: 
    https://www.youtube.com/watch?v=DhLO_ZaWaSg

    :biggrin: I don't know what.

    Remind me an JJ observation: an objasm32 debug program run crazy taking all core time if there is no DebugCenter.

    HSE