News:

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

Main Menu

Problems assembling SaveRegs and RestoreRegs

Started by markallyn, March 29, 2020, 09:50:36 AM

Previous topic - Next topic

markallyn

Hello everyone,

In the following trivial code I attempt to use the SaveRegs and RestoreRegs macros.  For some reason the code won't assemble leaving error messages to the effect that these two macros have syntax errors.

Quote
include \masm32\include64\masm64rt.inc

extrn   printf: PROC

.data
fmt   BYTE "It works!",13,10,0

.code
main   PROC   USES rcx
SaveRegs
sub   rsp, 40
invoke  printf, ADDR fmt
add     rsp, 40
waitkey
RestoreRegs

ret
main   ENDP
END

The waitkey macro works fine as does "invoke", so I take that to mean that the macros64 file referenced in masm32/include64/masm64rt.inc is being assembled.  I checked and both the macros are in the macros64.inc file. 

This is yet another amateur head-scratcher.

Regards,
Mark Allyn

HSE

Equations in Assembly: SmplMath

hutch--

Mark,

You are trying to mix technologies, if you want to manually set up a stack frame you can but masm64rt.inc sets a default stack frame. NOTE that the rcall macro is used in the example but you can use the invoke macro for all calls.

A distinction needs to be understood here between configuring 64 bit MASM and writing 64 bit MASM. The 64 bit version of MASM came unconfigured and it was a complex and messy workload to configure it properly whereas writing 64 bit MASM is reasonably straight forward. If you want to use independent EXTERNDEF prototypes, they must have a matching import library entry as well otherwise you will get a linker error.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    include \masm32\include64\masm64rt.inc

    .data
      txt db "Howdy Awl",13,10,0
      ptxt dq txt

    .code

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

entry_point proc       ; name of entry point for the linker

    USING r12           ; select the register(s) to preserve - not used in this example

    SaveRegs            ; save any selected registers

    rcall vc_printf, ptxt    ; MSVCRT is included in masm64rt.inc

    waitkey
    RestoreRegs         ; restore any selected registers
    .exit

entry_point endp

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

    end

markallyn

HSE and Hutch,

Gentlemen, thanks for your very timely response.  I think I see what you are proposing and I have incorporated your suggestions in the code.  Here it is as modified:

Quote
include \masm32\include64\masm64rt.inc

extrn   printf: PROC

.data
fmt   BYTE "It works!",13,10,0

.code
main   PROC   
USING   r12         ;assembler kicks out       

            ;syntax error for r12
SaveRegs         ;assembler kicks out       

            ;syntax error
sub   rsp, 40
invoke  printf, ADDR fmt   ;I'm aware of rcall
add     rsp, 40
waitkey
RestoreRegs         ;syntax error here too.
ret
main   ENDP
END



Unfortunately, as shown in my marginal comments the program still fails.  In addition to the "old" syntax errors for SaveRegs and RestoreRegs, I now get a syntax error on "r12".  I may of course not have understood what you were really getting at, and apologies if this is so.  I'd really like to use those register commands for non-volatiles as they are very neat and succinct.  And, BTW, I really adore "invoke".

Thanks again,
Mark

markallyn

Hutch,

The first sentence of your reply puzzled me ("You are trying to mix technologies"), and then I looked inside masm64rt.inc and saw the "STACKFRAME" directive and realized what I believe you were driving at.  Honestly, I'm not sure what all the implications are. 

If I continue to use the directive in masm64rt.inc and then proceed to set up my own stack does it really matter?  My understanding is that the PROC directive sets up a stack "automatically"; may not be true.  It seems to me that "doing my own stack" simply makes the STACKFRAME directive redundant.

On the other hand, if I ditched the PROC directive and relied on masm64rt.inc to do the frame, would subsequent code following the entry point actually run? 

Thanks for pointing this out!

Regards,
Mark

markallyn

Hutch,

Tried ditching just the "PROC" directive.  No doubt you will not be surprised to learn that I get a syntax error for "MAIN".

Mark

hutch--

Mark,

The example I did for you works perfectly. You must have a PROC ENDP pair in win64. Do not use manual stack settings as you risk messing up the alignment and it will not start. The STACKFRAME macro in masm64rt.inc sets the stack up correctly

> extrn   printf: PROC

This will not work. The line "rcall vc_printf, ptxt" has both the prototype AND a matching library by including masm64rt.inc, this is why it works correctly.

I tried to explain to you the difference between configuring 64 bit MASM and using it. Configuring it takes months of exhaustive testing where using the supported system is very similar to the 32 bit system.

The 32 bit versions of MASM come pre-configured with stack frames and invoke notation where the 64 bit version does not, the reason for months of work was to make the 64 bit version usable.

markallyn

Hutch,

I can see from your reply that I was missing a whole lot more than STACKFRAME in your reference to mixing technologies.

After my post I went back and looked at a debugger of my code when STACKFRAME was included via masm64rt.inc.  And, I saw that STACKFRAME added additional sub call for 96 bytes (?) in addition to the 40 I was requesting be "subbed".  Then I looked at the actual STACKFRAME macro and was rather shocked by its complexity. 

Next, I got rid of the 40 bytes I had subbed and added and the thing ran fine. 

I will try rcall as you suggest.  "Invoke" does the job at the moment.

But, this whole little adventure has me wondering whether I really want to use masm64rt.inc rather than simply linking in some libraries (kernel43.lib, msvcrt.lib) that I have used a lot.  The trouble is that thanks to your amazing perseverance there are many useful tools inside masm64rt that would be nice to access.

Regards as always,
Mark