Saving the volatile registers inside a procedure

Started by Vortex, May 01, 2025, 09:33:52 PM

Previous topic - Next topic

Vortex

Hello,

Here is a macro to save rcx,rdx,r8 and r9 to protect them across API function calls.

include SaveRegs.inc

SaveRegs MACRO

    LOCAL_rcx TEXTEQU <LOCAL _rcx:QWORD>
    LOCAL_rdx TEXTEQU <LOCAL _rdx:QWORD>
    LOCAL_r8  TEXTEQU <LOCAL _r8:QWORD>
    LOCAL_r9  TEXTEQU <LOCAL _r9:QWORD>

    LOCAL_rcx
    LOCAL_rdx
    LOCAL_r8
    LOCAL_r9

    mov _rcx,rcx
    mov _rdx,rdx
    mov _r8,r8
    mov _r9,r9

ENDM

.data

msg     db 'Hello!',0
msg2    db 'rcx,rdx,r8 and r9 are saved.',0
title   db 'MsgBox',0
title2  db 'Macro test',0

.code

start:

    sub     rsp,8+4*8
    invoke  main,ADDR msg2,ADDR title2

    invoke  ExitProcess,0

main PROC x:QWORD,y:QWORD PARMAREA=4*SIZEOF QWORD

    SaveRegs

    invoke  MessageBox,0,ADDR msg,ADDR title,0
   
;   The first call to MessageBox destroys rcx,rdx,r8 and r9

    invoke  MessageBox,0,_rcx,_rdx,0
   
    invoke  ExitProcess,0

main ENDP

END start
Code it... That's all...

Quin

Cool stuff, thanks Vortex! Works here with latest Poasm :)
Use the assembly, Luke.

Vortex

Hi Quin,

Thanks for your test. This modified version where the non-volatile registers are preserved works as expected :

main PROC uses rsi rdi rbx x:QWORD,y:QWORD PARMAREA=4*SIZEOF QWORD

    SaveRegs

    xor     rsi,rsi
    mov     rdi,1
    mov     rbx,2

    invoke  MessageBox,0,ADDR msg,ADDR title,0
   
;   The first call to MessageBox destroys rcx,rdx,r8 and r9

    invoke  MessageBox,0,_rcx,_rdx,0
   
    invoke  ExitProcess,0

main ENDP
Code it... That's all...