News:

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

Main Menu

FRAME issues

Started by aw27, October 16, 2017, 05:31:52 PM

Previous topic - Next topic

johnsa

www.terraspace.co.uk/uasm64.zip

Try this one now.

The follow examples all work perfectly:


option casemap:none
option frame:NOAUTO

includelib c:\jwasm\wininc\lib64\kernel32.lib
ExitProcess proto :dword

.code

OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
proc2 proc FRAME par1:qword, par2:qword
db 048h
      push rbp
.pushreg rbp
mov rbp, rsp
.setframe rbp, 0
sub rsp, 60h
      .allocstack 60h
.endprolog
mov par1, rcx
mov par2, rdx
leave
ret
proc2 endp
OPTION PROLOGUE:PROLOGUEDEF
OPTION EPILOGUE:EPILOGUEDEF

proc1 proc FRAME par1:qword, par2:qword
.endprolog
mov par1,rcx
mov par2,rdx
ret
proc1 endp

proc3 proc FRAME
      db      048h
      push    rbp
      .pushreg rbp
      mov rbp, rsp
     .setframe rbp, 0
    .endprolog
    ret
proc3 endp

main proc
sub rsp,20h
call mainE
call proc1
call proc2
add rsp,20h
mov ecx,0
call ExitProcess
ret
main endp

ExceptionHandler proc
    ret
ExceptionHandler endp

mainE proc frame:ExceptionHandler
    .endprolog
    ret
mainE endp
end


and


.x64
.model flat, fastcall

option frame:auto
option  dllimport:<msvcrt>
printf  proto :ptr, :vararg
exit    proto :dword
option  dllimport:none

.data
string db "ExceptionHandler called",10,0
.code

ExceptionHandler PROC
    invoke printf, addr string
    invoke exit,0
    ret
ExceptionHandler ENDP

main proc frame:ExceptionHandler

    xor rax,rax
    mov [rax],al
    ret

main endp

    end main


and


.x64
.model flat, fastcall

option  dllimport:<msvcrt>
printf  proto :ptr, :vararg
exit    proto :dword
option  dllimport:none

.data
string db "ExceptionHandler called",10,0
.code

ExceptionHandler PROC
    invoke printf, addr string
    invoke exit,0
    ret
ExceptionHandler ENDP

main proc frame:ExceptionHandler

    .endprolog
    xor rax,rax
    mov [rax],al
    ret

main endp

    end main


results:

D:\HJWasm\Tests>build

D:\HJWasm\Tests>uasm64 -c -nologo -less -Zi -Zd -win64 -Zp8 nid_frame.asm
nid_frame.asm(2) : Warning A4095: Multiple .MODEL directives, .MODEL ignored
nid_frame.asm: 1 warnings, 0 errors

D:\HJWasm\Tests>uasm64 -c -nologo -less -Zi -Zd -win64 -Zp8 nid_frame2.asm
nid_frame2.asm(2) : Warning A4095: Multiple .MODEL directives, .MODEL ignored
nid_frame2.asm: 1 warnings, 0 errors

D:\HJWasm\Tests>uasm64 -c -nologo -less -Zi -Zd -win64 -Zp8 aw27_frame.asm
aw27_frame.asm: ok

D:\HJWasm\Tests>"C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.10.25017\bin\HostX86\x64\link.exe" /subsystem:console /machine:x64 /Libpath:"d:\winsdk\v7.1\Lib\x64" nid_frame.obj msvcrt.lib
Microsoft (R) Incremental Linker Version 14.10.25017.0
Copyright (C) Microsoft Corporation.  All rights reserved.


D:\HJWasm\Tests>"C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.10.25017\bin\HostX86\x64\link.exe" /subsystem:console /machine:x64 /Libpath:"d:\winsdk\v7.1\Lib\x64" nid_frame2.obj msvcrt.lib
Microsoft (R) Incremental Linker Version 14.10.25017.0
Copyright (C) Microsoft Corporation.  All rights reserved.


D:\HJWasm\Tests>"C:\Program Files (x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\14.10.25017\bin\HostX86\x64\link.exe" /subsystem:console /machine:x64 /Libpath:"d:\winsdk\v7.1\Lib\x64" /entry:main aw27_frame.obj
Microsoft (R) Incremental Linker Version 14.10.25017.0
Copyright (C) Microsoft Corporation.  All rights reserved.


D:\HJWasm\Tests>nid_frame
ExceptionHandler called

D:\HJWasm\Tests>nid_frame2
ExceptionHandler called






johnsa

Did you have a chance to try that updated version yet?

John

aw27

Quote from: johnsa on October 20, 2017, 07:29:04 PM
Did you have a chance to try that updated version yet?

John
I had a look now at the first case you sport above.
I don't think it is what is needed, when FRAME is NOAUTO the function should be completely dumb and you make it a little smart. JWASM makes it dumb as well as MASM.
For example, for proc1 the listing of UASM is:
00000013                        proc1 proc FRAME par1:qword, par2:qword
                                   .endprolog
00000013  55                *   push rbp
00000014  488BEC            *   mov rbp, rsp
00000017  48894D10                 mov par1,rcx
0000001B  48895518                 mov par2,rdx
0000001F                           ret
0000001F  5D                *   pop rbp
00000020  C3                *   retn

JWASM does:
00000013                        proc1 proc FRAME par1:qword, par2:qword
                                   .endprolog
00000013  48894D10                 mov par1,rcx
00000017  48895518                 mov par2,rdx
0000001B                           ret
0000001B  C3                *   retn

You are pushing rbp after the prolog and this causes problems, for the unwinding in case of exception.

This is different from what would happen if you had not put FRAME.
Here MASM would put push rbp at least to align the stack. I did not check JWASM here, but I expect it to do the same.

johnsa

Ok,

So I've set it so it won't attempt to add any prologue unless frame auto. in the case of this proc1 it obviously crashes, as par1/2 are not setup in terms of a stack frame. but the disasm is:


proc1 proc FRAME par1:qword, par2:qword
.endprolog
mov par1,rcx
00007FF71A1D1063  mov         qword ptr [par1],rcx 
mov par2,rdx
00007FF71A1D1067  mov         qword ptr [par2],rdx 
ret
00007FF71A1D106B  ret 
proc1 endp


Are you ok with that and the assumption that the crash is expected?

aw27

Quote from: johnsa on October 20, 2017, 09:30:57 PM
Are you ok with that and the assumption that the crash is expected?

With NOAUTO we need to handle the epilog. This is what JWASM does and it works well on this.
If you follow JWASM you will be good.
It must work without default Epilog and Prolog even if you don't set both to none.

This must not crash:

OPTION PROLOGUE:PROLOGUEDEF
OPTION EPILOGUE:EPILOGUEDEF

proc1 proc FRAME par1:qword, par2:qword
db 048h
      push rbp
.pushreg rbp
mov rbp, rsp
.setframe rbp, 0
.endprolog
int 3
mov par1,rcx
mov par2,rdx

; epilog
        leave
        ; or
;pop rbp
;mov rsp, rbp
ret
proc1 endp


This is how JWASM assembles it:

00000001`40001013 4855            push    rbp
00000001`40001015 488bec          mov     rbp,rsp
;00000001`40001018 cc              int     3
00000001`40001019 48894d10        mov     qword ptr [rbp+10h],rcx
00000001`4000101d 48895518        mov     qword ptr [rbp+18h],rdx
00000001`40001021 c9              leave
00000001`40001022 c3              ret



johnsa

Test piece:



option casemap:none
option frame:NOAUTO

includelib c:\jwasm\wininc\lib64\kernel32.lib
ExitProcess proto :dword

.code

OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
proc2 proc FRAME par1:qword, par2:qword
db 048h
      push rbp
.pushreg rbp
mov rbp, rsp
.setframe rbp, 0
sub rsp, 60h
      .allocstack 60h
.endprolog
mov par1, rcx
mov par2, rdx
leave
ret
proc2 endp
OPTION PROLOGUE:PROLOGUEDEF
OPTION EPILOGUE:EPILOGUEDEF

proc1 proc FRAME par1:qword, par2:qword
.endprolog
mov par1,rcx
mov par2,rdx
ret
proc1 endp

proc3 proc FRAME
      db      048h
      push    rbp
      .pushreg rbp
      mov rbp, rsp
     .setframe rbp, 0
    .endprolog
    ret
proc3 endp

proc4 proc FRAME par1:qword, par2:qword
db 048h
      push rbp
.pushreg rbp
mov rbp, rsp
.setframe rbp, 0
sub rsp, 60h
      .allocstack 60h
.endprolog
mov par1, rcx
mov par2, rdx
leave
ret
proc4 endp

main proc
sub rsp,20h
call mainE
;call proc1
call proc2
;call proc3
call proc4
add rsp,20h
mov ecx,0
call ExitProcess
ret
main endp

ExceptionHandler proc
    ret
ExceptionHandler endp

mainE proc frame:ExceptionHandler
    .endprolog
    ret
mainE endp
end



From this..

1) proc1 will crash as no stack frame is setup. (I believe that should be the expected result)

2) proc2, mainE and proc4 work perfectly.

3) proc3 is a problem now however. As it has no locals and no arguments the assumption is that it should use FPO, therefor there is an extra sub rsp,8 and add rsp,8 in the proc.. which is meant to account for the lack of push rbp, which has been manually added. Given there is also no corresponding leave or pop rbp it crashes.
If we add the pop rbp everything works, however the stack is unaligned due to the sub and push combined.
I don't think there is anything I can do about that apart from having an option to disable FPO (like forceframe) or as the programmer you'd be expected to know that particular proc should be coded as FPO.

aw27

As mentioned earlier, if you compare what you get with UASM with what JWASM gets you will end fixing everything. In my opinion JWASM handles even better than MASM this stuff - MASM becomes confused when you use parameters in a procedure with FRAME (it should give error but does not and simply garbles things).

I don't thing you should add anything for Proc 3, the developer should do it in the prolog (i.e. sub rsp,8 followed by .allocstack 8 ), because if there is an exception, the exception handler will know it must unwind those bytes . The developer must also add manually the add rsp, 8 in the epilog.

johnsa

Done :) 2.43 will be out shortly with this fix plus:

1) console colouring (just because it's funky)
2) new operators ARGIDX(arg) and ARGSIZE(arg) which tell you the size in bytes of a PROC parameter and it's ordinal (1.. n including varargs).
3) Using 2 a new macro in the library for use with SYSTEM V ABI to map a parameter (which is either in register or stack) to a local or equate referring to the stack as SYSTEMV ABI has no notion of shadow space.
4) Some new features and support for inline 128 records to and from memory or xmm regs.

aw27

Quote from: johnsa on October 21, 2017, 02:04:41 AM
4) Some new features and support for inline 128 records to and from memory or xmm regs.
What you have now is loading records, which is good.
But as records are becoming bigger and bigger, what about an internal macro to retrieve its fields?  ;)


johnsa

Will do. I believe the mask operator should be extended to support 128bits ... so next will be some macro or operator to extract a specified field. :)