News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Hutchs mcalc3 Project - UASM mod

Started by LiaoMi, October 23, 2019, 01:15:47 AM

Previous topic - Next topic

LiaoMi

Hi,

I'm trying to build a project mcalc3 using original masm64 macros and UASM, problems appear in the library m64lib.lib ... in the test project the same errors occur as before.

.486
.MMX
.XMM
.x64

option casemap:none
OPTION CODEVIEW:1
option win64:15;win64:11
option frame:auto; noauto
option stackbase:rsp
option dotname
option evex:1
;option proc:private
option LITERALS:ON
;option PROCALIGN:16
OPTION FIELDALIGN:16; 1|2|4|8|16|32 - The default value is 1 or the value set by cmdline switch -Zp
       
.nolist
.nocref

    USHORT typedef WORD
    ULONG typedef DWORD
   
    include C:\masm64\m64lib\m64lib.lib
    includelib C:\masm64\m64lib\m64lib.inc

.data
;align 8
_COA struct
Val3 WORD 0
Val4 ULONG 0
Val5 WORD 0
Val6 ULONG 0
_COA ends

Val1 USHORT 0
Val2 ULONG 0

COA _COA <?>

COAsz equ sizeof COA
ValX qword 0ddddddddddddddddh

.code
align 16
mainCRTStartup proc PUBLIC
    mov rbx,COAsz
    mov Val1,1
    mov Val2,2
   
    assume rax:ptr _COA
   
    lea rax, COA
    mov [rax].Val3, 5
    mov [rax].Val4, 6
    mov [rax].Val5, 7
    mov [rax].Val6, 8
   
    ret
mainCRTStartup endp
end


that's what goes to the log, watch attachment  :arrow_right:

I think, okay, you can build this library yourself. Of course, I decided to do it with the help of UASM. Many errors arise again, some of which I fixed by replacing the function call with a macro that does not check the parameters of the function.

Quotem64libUASM.asm(1006) : Error A2160: INVOKE requires prototype for procedure
len(1)[macros64.inc]: Macro called from
  m64libUASM.asm(1006): Main line code
m64libUASM.asm(1007) : Error A2145: INVOKE argument type mismatch: argument 2
alloc(1)[macros64.inc]: Macro called from
  m64libUASM.asm(1007): Main line code
m64libUASM.asm(1007) : Error A2048: Operands must be the same size: 4 - 8
alloc(1)[macros64.inc]: Macro called from
  m64libUASM.asm(1007): Main line code
m64libUASM.asm(1677) : Error A2160: INVOKE requires prototype for procedure
m64libUASM.asm(1678) : Error A2160: INVOKE requires prototype for procedure
len(1)[macros64.inc]: Macro called from
  m64libUASM.asm(1678): Main line code
m64libUASM.asm(1987) : Error A2136: Symbol type conflict: hextable
m64libUASM.asm(2107) : Error A2184: Use of register assumed to ERROR
m64libUASM.asm(2141) : Error A2145: INVOKE argument type mismatch: argument 2
alloc(1)[macros64.inc]: Macro called from
  m64libUASM.asm(2141): Main line code
m64libUASM.asm(2141) : Error A2048: Operands must be the same size: 4 - 8
alloc(1)[macros64.inc]: Macro called from
  m64libUASM.asm(2141): Main line code
m64libUASM.asm(2495) : Error A2145: INVOKE argument type mismatch: argument 2
m64libUASM.asm(2495) : Error A2145: INVOKE argument type mismatch: argument 3
m64libUASM.asm(2495) : Error A2048: Operands must be the same size: 4 - 8
m64libUASM.asm(2495) : Error A2048: Operands must be the same size: 4 - 8
m64libUASM.asm(2496) : Error A2145: INVOKE argument type mismatch: argument 2
m64libUASM.asm(2496) : Error A2145: INVOKE argument type mismatch: argument 3
m64libUASM.asm(2496) : Error A2048: Operands must be the same size: 4 - 8
m64libUASM.asm(2496) : Error A2048: Operands must be the same size: 4 - 8
m64libUASM.asm(2500) : Error A2147: Too few arguments to INVOKE: ReleaseDC
m64libUASM.asm(2739) : Error A2145: INVOKE argument type mismatch: argument 2
alloc(1)[macros64.inc]: Macro called from
  m64libUASM.asm(2739): Main line code
m64libUASM.asm(2739) : Error A2048: Operands must be the same size: 4 - 8
alloc(1)[macros64.inc]: Macro called from
  m64libUASM.asm(2739): Main line code
m64libUASM.asm(2740) : Error A2145: INVOKE argument type mismatch: argument 3
m64libUASM.asm(2740) : Error A2048: Operands must be the same size: 4 - 8
m64libUASM.asm(2775) : Error A2160: INVOKE requires prototype for procedure
m64libUASM.asm(2776) : Error A2160: INVOKE requires prototype for procedure
m64libUASM.asm(2777) : Error A2160: INVOKE requires prototype for procedure
m64libUASM.asm(2896) : Error A2145: INVOKE argument type mismatch: argument 2
alloc(1)[macros64.inc]: Macro called from
  m64libUASM.asm(2896): Main line code
m64libUASM.asm(2896) : Error A2048: Operands must be the same size: 4 - 8
alloc(1)[macros64.inc]: Macro called from
  m64libUASM.asm(2896): Main line code
m64libUASM.asm(3339) : Error A2102: Symbol not defined : OPENFILENAME

I took the first remaining error - m64libUASM.asm(1006), copied the macro that should use API.

mainCRTStartup proc PUBLIC
    mov rbx,COAsz
    mov Val1,1
    mov Val2,2
   
    mov r14, alloc(r13)
   
    assume rax:ptr _COA
   
    lea rax, COA
    mov [rax].Val3, 5
    mov [rax].Val4, 6
    mov [rax].Val5, 7
    mov [rax].Val6, 8
   
    ret
mainCRTStartup endp
end


main.asm(64) : Error A2145: INVOKE argument type mismatch: argument 2
alloc(1)[main.asm]: Macro called from
  main.asm(64): Main line code
main.asm(64) : Error A2048: Operands must be the same size: 4 - 8
alloc(1)[main.asm]: Macro called from
  main.asm(64): Main line code


:arrow_down:

  ; -------------
  ; memory macros
  ; -------------
    alloc MACRO bsize
      invoke GlobalAlloc,GMEM_FIXED or GMEM_ZEROINIT,bsize
      EXITM <rax>
    ENDM


In my SDK, the definition is indicated as follows .. GlobalAlloc PROTO uFlags:DWORD ,dwBytes:DWORD

:arrow_down:

dwBytes:DWORD = bsize = r13

mov r14, alloc(r13) - error

mov r14, alloc(eax) - compiles successfully!

What is right and what is not ?! Is it a bug when processing macros in UASM or is it a bug in macros from MASM64, where the bit depth of the variable is not taken into account? It seems to me that all the errors that have come out depend on this. The library from masm64 is not suitable for UASM, this is a separate error.

Dear Specialists, I am waiting for your advice  :rolleyes:


hutch--

I can't digest all of it but the format of masm64 I have used makes GlobalAlloc use 2 x QWORD variables. The only time I use DWORD is for structures that contain DWORD sized data. a RECT structure is 4 x DWORD members and where I need to place them into a mnemonic, I load eax and pass it as rax. Same with all registers.

Now with API calls, you will have to correctly prototype each one for UASM, MASM does not use them. For most of the common API calls you can pull them out of the 32 bit version of masm and change the DWORD data size to QWORD and it usually works OK.

LiaoMi

Thank you, Hutch! I should have guessed, but I was completely confused.

GlobalAlloc (
    __in UINT uFlags,
    __in SIZE_T dwBytes
    );

What's sizeof(size_t) on 32-bit vs the various 64-bit data models?
https://stackoverflow.com/questions/918787/whats-sizeofsize-t-on-32-bit-vs-the-various-64-bit-data-models
For clarification: SIZE_MAX is one of the macros in 7.18.3.2, whose implementation-defined value shall be equal to or greater in magnitude (absolute value) than the corresponding value given below, with the same sign., that is, 65535 is the minimum value which is an acceptable limit for the size of size_t, but it can be (and usually is) much larger.

What is size_t in C?
https://stackoverflow.com/questions/2550774/what-is-size-t-in-c

QuoteNow with API calls, you will have to correctly prototype each one for UASM, MASM does not use them.

Explains why everything works with an Invoke(macros64) macro.

Such subtleties are not taken into account in the SDK (Full SDK 10.0 translate for 64 and 32 bits by ToutEnMasm), where you can use QWord it is not used  :undecided:, too strict rules were applied here.

Notes - https://en.cppreference.com/w/c/types/size_t
size_t can store the maximum size of a theoretically possible object of any type (including array).
size_t is commonly used for array indexing and loop counting. Programs that use other types, such as unsigned int, for array indexing may fail on, e.g. 64-bit systems when the index exceeds UINT_MAX or if it relies on 32-bit modular arithmetic.

SDK needs to be manually corrected or simply overridden by the prototype wherever it is used.

Thanks again!  :thumbsup:

aw27

Hi LaioMi

size_t typedef ptr
works fine for 32-bit and 64-bit, you don't need anything else to make  it work for every prototype.  :thumbsup:

LiaoMi

Quote from: AW on October 23, 2019, 05:27:32 AM
Hi LaioMi

size_t typedef ptr
works fine for 32-bit and 64-bit, you don't need anything else to make  it work for every prototype.  :thumbsup:

Hi AW,

yes  :thumbsup:, ptr is the best option, I have to update the whole SDK, I wanted to avoid this procedure, but I have to do it.

intsafe.h
#ifdef _WIN64
typedef __int64             ptrdiff_t;
typedef unsigned __int64    size_t;
#else
typedef _W64 int            ptrdiff_t;
typedef _W64 unsigned int   size_t;
#endif


Here the wrong rule is used to convert this type
SIZE_T = DWORD ; intsafe.h
size_t = DWORD ; intsafe.h

and here is the correct entry - PSIZE_T = XMASM, XMASM  = ptr

Hopefully there are not many type matches  :skrewy:

aw27

If you change your code to:
    include \masm32\m64lib\m64lib.inc
    includelib \masm32\m64lib\m64lib.lib

instead of this:
    include \masm32\m64lib\m64lib.lib
    includelib \masm32\m64lib\m64lib.inc

it will:


:biggrin:

hutch--

#6
This is the one that I modified some of the 32 bit version of MASM's prototypes.

AbortDoc PROTO :PTR
AbortPath PROTO :PTR
AddFontMemResourceEx PROTO :PTR,:PTR,:PTR,:PTR

AddFontResourceA PROTO :PTR
IFNDEF __UNICODE__
  AddFontResource equ <AddFontResourceA>
ENDIF

AddFontResourceExA PROTO :PTR,:PTR,:PTR
IFNDEF __UNICODE__
  AddFontResourceEx equ <AddFontResourceExA>
ENDIF

AddFontResourceExW PROTO :PTR,:PTR,:PTR
IFDEF __UNICODE__
  AddFontResourceEx equ <AddFontResourceExW>
ENDIF

AddFontResourceW PROTO :PTR
IFDEF __UNICODE__
  AddFontResource equ <AddFontResourceW>
ENDIF

AngleArc PROTO :PTR,:PTR,:PTR,:PTR,:PTR,:PTR
AnimatePalette PROTO :PTR,:PTR,:PTR,:PTR
Arc PROTO :PTR,:PTR,:PTR,:PTR,:PTR,:PTR,:PTR,:PTR,:PTR
ArcTo PROTO :PTR,:PTR,:PTR,:PTR,:PTR,:PTR,:PTR,:PTR,:PTR
BeginPath PROTO :PTR
BitBlt PROTO :PTR,:PTR,:PTR,:PTR,:PTR,:PTR,:PTR,:PTR,:PTR
CancelDC PROTO :PTR
CheckColorsInGamut PROTO :PTR,:PTR,:PTR,:PTR
ChoosePixelFormat PROTO :PTR,:PTR
Chord PROTO :PTR,:PTR,:PTR,:PTR,:PTR,:PTR,:PTR,:PTR,:PTR
CloseEnhMetaFile PROTO :PTR
CloseFigure PROTO :PTR
CloseMetaFile PROTO :PTR
ColorCorrectPalette PROTO :PTR,:PTR,:PTR,:PTR
ColorMatchToTarget PROTO :PTR,:PTR,:PTR
CombineRgn PROTO :PTR,:PTR,:PTR,:PTR
CombineTransform PROTO :PTR,:PTR,:PTR

LiaoMi

Quote from: AW on October 23, 2019, 06:47:28 AM
If you change your code to:
    include \masm32\m64lib\m64lib.inc
    includelib \masm32\m64lib\m64lib.lib

instead of this:
    include \masm32\m64lib\m64lib.lib
    includelib \masm32\m64lib\m64lib.inc

it will:


:biggrin:

Hi AW,

learned something again  :biggrin:  :skrewy: Thank you!

hutch--

LiaoMi,

Something that will help if you don't already know it is how the FASTCALL convention works in Win64. Apart from the registers for the first 4 arguments you also have shadow space and importantly the argument alignment is always 8 bytes. In this 8 bytes you can place byte, word, dword and qword. When you prototype an API or a procedure you can generally assume that the data size can be a QWORD. John has done the invoke technique correctly and the data alignment works according to the Microsoft ABI.

Where you have to deviate from this is with structures, many of which are DWORD or have DWORD members.

Vortex

A quick way to replace (Q)WORDs with :PTRs :

busybox.exe sed -i -b "s/:QWORD/:PTR/g" kernel32.inc

hutch--

 :biggrin:

Hi Erol,

At the risk of self promotion, my QE does global replace really well and fast.

LiaoMi

The project is not abandoned, I converted a new SDK, new prototypes for the preprocessor were added there, they cause errors, so I must first clean up the SDK or automate the process in the future. There is not much time to do this. But this task is a priority ..