The MASM Forum

Microsoft 64 bit MASM => Examples => Topic started by: hutch-- on July 21, 2018, 01:41:21 AM

Title: Plenty of registers with no stack frame.
Post by: hutch-- on July 21, 2018, 01:41:21 AM
I have toyed with this idea for a while, the MMX functionality has been superseded by SSE/AVX and there are 8 64 bit registers that are usually not used for anything and as Win64 integer registers are also 64 bit, the logic was to make use of them for storage, in this case, the preservation of non-volatile registers in procedures that have no stack frame.

It comes at the price that if you wish to use the same set of aliased registers for floating point operations, you will need to use the "emms" mnemonic to clear the multi-media state before you perform floating point operations. Now be warned that using a technique like this is politically incorrect, illegal, immoral and fattening but it seems to work OK.  :P

The output for this test piece is as follows.

Before 0 0 0 0 0 0 0 1376080
During 1 2 3 4 5 6 7 8
After  0 0 0 0 0 0 0 1376080
Press any key to continue...

The example.

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

    include \masm32\include64\masm64rt.inc

    .code

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

entry_point proc

    conout "Before ",str$(rbx)," ",str$(r12)," ",str$(r13)," ",str$(r14)," ", \
           str$(r15)," ",str$(rsi)," ",str$(rdi)," ",str$(rbp),lf

    call testme

    conout "After  ",str$(rbx)," ",str$(r12)," ",str$(r13)," ",str$(r14)," ", \
           str$(r15)," ",str$(rsi)," ",str$(rdi)," ",str$(rbp),lf

    waitkey

    invoke ExitProcess,0

    ret

entry_point endp

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

NOSTACKFRAME

testme proc

    movq mm0, rbx
    movq mm1, r12
    movq mm2, r13
    movq mm3, r14
    movq mm4, r15
    movq mm5, rsi
    movq mm6, rdi
    movq mm7, rbp

    mov rbx, 1
    mov r12, 2
    mov r13, 3
    mov r14, 4
    mov r15, 5
    mov rsi, 6
    mov rdi, 7
    mov rbp, 8

    conout "During ",str$(rbx)," ",str$(r12)," ",str$(r13)," ",str$(r14)," ", \
           str$(r15)," ",str$(rsi)," ",str$(rdi)," ",str$(rbp),lf

    movq rbx, mm0
    movq r12, mm1
    movq r13, mm2
    movq r14, mm3
    movq r15, mm4
    movq rsi, mm5
    movq rdi, mm6
    movq rbp, mm7

    ret

testme endp

STACKFRAME

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

    end
Title: Re: Plenty of registers with no stack frame.
Post by: HSE on July 21, 2018, 02:11:18 AM
Quote from: hutch-- on July 21, 2018, 01:41:21 AM
... and fattening ...
:biggrin: :biggrin: :biggrin:
Title: Re: Plenty of registers with no stack frame.
Post by: jimg on July 21, 2018, 03:04:37 AM
Seems like it would be a nightmare trying to keep track of which proc did what and not call another proc that did the same thing, thus wiping out your values?
Title: Re: Plenty of registers with no stack frame.
Post by: hutch-- on July 21, 2018, 03:38:07 AM
Jim,

Procedures with no stack frame are generally not well suited for calling other procedures so its not really a problem when you are writing leaf procedures. If you want a call tree, use a stack frame as you have no effective depth limit. Without the extra 8 registers it is far more difficult to build a call tree as you only have the volatile registers which are rax, rcx, rdx r8 - 11.
Title: Re: Plenty of registers with no stack frame.
Post by: hutch-- on July 21, 2018, 05:06:02 PM
The XMM registers work just as well if you wish to run floating point without switching between MMX and FP with "emms".

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

NOSTACKFRAME

testme proc

    movq xmm0, rbx
    movq xmm1, r12
    movq xmm2, r13
    movq xmm3, r14
    movq xmm4, r15
    movq xmm5, rsi
    movq xmm6, rdi
    movq xmm7, rbp

    mov rbx, 1
    mov r12, 2
    mov r13, 3
    mov r14, 4
    mov r15, 5
    mov rsi, 6
    mov rdi, 7
    mov rbp, 8

    conout "During ",str$(rbx)," ",str$(r12)," ",str$(r13)," ",str$(r14)," ", \
                     str$(r15)," ",str$(rsi)," ",str$(rdi)," ",str$(rbp),lf

    movq rbx, xmm0
    movq r12, xmm1
    movq r13, xmm2
    movq r14, xmm3
    movq r15, xmm4
    movq rsi, xmm5
    movq rdi, xmm6
    movq rbp, xmm7

    ret

testme endp

STACKFRAME

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
Title: Re: Plenty of registers with no stack frame.
Post by: jj2007 on July 21, 2018, 06:21:09 PM
I am surprised that conout doesn't trash the volatile xmm regs. That may depend on the Windows version, of course.
Title: Re: Plenty of registers with no stack frame.
Post by: hutch-- on July 21, 2018, 06:34:13 PM
There is probably no reason why the API code used in "conout" would need to use xmm registers as  console display does nothing exciting and the data transfer rate is very slow.
Title: Re: Plenty of registers with no stack frame.
Post by: jj2007 on July 21, 2018, 07:08:51 PM
Yes, probably.