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

aw27

ISSUE NUMBER ONE:

Let's consider the following code:


option casemap:none
;option frame:auto ; no AUTO

includelib \masm32\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
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
proc1 endp

main proc
sub rsp, 8
int 3

sub rsp, 20h
call proc1
call proc2
add rsp, 20h

add rsp, 8
mov ecx, 0
call ExitProcess
main endp

end



UASM
proc2
00000001`40001000 4855            push    rbp
00000001`40001002 488bec          mov     rbp,rsp
00000001`40001005 4883ec60        sub     rsp,60h
00000001`40001009 48894c2410      mov     qword ptr [rsp+10h],rcx
00000001`4000100e 4889542418      mov     qword ptr [rsp+18h],rdx
00000001`40001013 c9              leave
00000001`40001014 c3              ret
proc1
00000001`40001015 4855            push    rbp
00000001`40001017 488bec          mov     rbp,rsp
00000001`4000101a 55              push    rbp
00000001`4000101b 488bec          mov     rbp,rsp
00000001`4000101e 4883ec60        sub     rsp,60h
00000001`40001022 48894d10        mov     qword ptr [rbp+10h],rcx
00000001`40001026 48895518        mov     qword ptr [rbp+18h],rdx
00000001`4000102a c9              leave
00000001`4000102b 5d              pop     rbp
00000001`4000102c c3              ret

MASM
proc2
00000001`40001000 4855            push    rbp
00000001`40001002 488bec          mov     rbp,rsp
00000001`40001005 4883ec60        sub     rsp,60h
00000001`40001009 48894d10        mov     qword ptr [rbp+10h],rcx
00000001`4000100d 48895518        mov     qword ptr [rbp+18h],rdx
00000001`40001011 c9              leave
proc1
00000001`40001012 4855            push    rbp
00000001`40001014 488bec          mov     rbp,rsp
00000001`40001017 4883ec60        sub     rsp,60h
00000001`4000101b 48894d10        mov     qword ptr [rbp+10h],rcx
00000001`4000101f 48895518        mov     qword ptr [rbp+18h],rdx
00000001`40001023 c9              leave

JWASM
proc2
00000001`40001000 4855            push    rbp
00000001`40001002 488bec          mov     rbp,rsp
00000001`40001005 4883ec60        sub     rsp,60h
00000001`40001009 48894d10        mov     qword ptr [rbp+10h],rcx
00000001`4000100d 48895518        mov     qword ptr [rbp+18h],rdx
00000001`40001011 c9              leave
00000001`40001012 c3              ret
proc1
00000001`40001013 4855            push    rbp
00000001`40001015 488bec          mov     rbp,rsp
00000001`40001018 4883ec60        sub     rsp,60h
00000001`4000101c 48894d10        mov     qword ptr [rbp+10h],rcx
00000001`40001020 48895518        mov     qword ptr [rbp+18h],rdx
00000001`40001024 c9              leave
00000001`40001025 c3              ret

In main proc UASM also unexpectedly adds sub rsp,8 but does not add rsp, 8 in the epilog.
As a side note, appears that MASM is also buggy because the RET after the LEAVE disappear.

ISSUE NUMBER TWO:

OPTION LITERALS:ON does not work when FRAME is not AUTO




johnsa

Hi,

I'll check the literals with frame stuff shortly.

With regards to the example you've posted there are a couple of notes:

the add rsp,8 is missing because there is no RET after the exitprocess, RET is what triggers epilogue generation.
You can't mix custom prologue with a normal FRAME proc in uasm as you'll get duplicated prologue. If you're putting in custom prologue you need to use either option proc:none (which is shorthand for option prologue:none and option epilogue:none) or use a custom macro. FRAME in ML doesn't generate prologue which is why it has only the one copy.

aw27

Quote from: johnsa on October 16, 2017, 08:45:12 PM
You can't mix custom prologue with a normal FRAME proc in uasm as you'll get duplicated prologue. If you're putting in custom prologue you need to use either option proc:none (which is shorthand for option prologue:none and option epilogue:none) or use a custom macro. FRAME in ML doesn't generate prologue which is why it has only the one copy.
Things are becoming a bit confusing, particularly because FRAME without FRAME:AUTO should not work like that.  It contradicts both MASM and JWASM, which deals very well with all this.
And how to fill the HOME Shadow space with the registers values if UASM keeps using the ESP as frame pointer after I set EBP as frame pointer? I don't see any way.

johnsa

That first one was a bug in 2.42 which is now already fixed, it shouldn't have reverted to rsp in that case.
We forced all procs in 64bit to frame auto to simplify the number of options and to also remove the need to even use the frame keyword, so all procs are FRAME+FRAME:AUTO, unless you switch off prologue/epilogue to write your own "raw" proc. I always thought the whole FRAME thing was pretty pointless having to use it in combination with FRAME:AUTO etc. Why would you want anything but a frame proc or a raw proc ?
I'm happy to look at changing this behaviour if someone has a convincing argument :) I don't care about ML64 compatibility.

Do you have an example with the literals not working ? I've tried it this side without frame:auto and it's working.

aw27

Quote from: johnsa on October 16, 2017, 09:25:53 PM
I always thought the whole FRAME thing was pretty pointless
It is not pointless, don't despise the intelligence of people that have thought about that before you :(.
It is fundamental for the Exception Handling, something I am working at the moment. FRAME:AUTO is pointless for anything useful concerning Exception Handling. If you can't fix it, leave it but I can't use UASM as it is for that.

hutch--

Good idea to dump something that is useless and confusing. What you are proposing is what I already do in 64 bit MASM, the choice of with or without a stack frame. It is useful to control the alignment as a user defined variable as it makes larger that 64 bit LOCAL variables viable by placing them at the top of the procedure. To simplify the usage, I have 2 basic wrapper types of macros,

STACKFRAME
NOSTACKFRAME

johnsa

Quote from: aw27 on October 16, 2017, 09:34:42 PM
Quote from: johnsa on October 16, 2017, 09:25:53 PM
I always thought the whole FRAME thing was pretty pointless
It is not pointless, don't despise the intelligence of people that have thought about that before you :(.
It is fundamental for the Exception Handling, something I am working at the moment. FRAME:AUTO is pointless for anything useful concerning Exception Handling. If you can't fix it, leave it but I can't use UASM as it is for that.

FRAME will add the .pdata record, which is the default now even if you don't specify frame.. you can still use frame:<handler> if you need a custom one.
So what I'm saying is that you have full exception handling support built-in the prologue with all the pseudo-ops already, no need to add them manually.. unless you write a raw proc and have a specific requirement ?

aw27

Quote from: johnsa on October 16, 2017, 09:47:31 PM
Quote from: aw27 on October 16, 2017, 09:34:42 PM
Quote from: johnsa on October 16, 2017, 09:25:53 PM
I always thought the whole FRAME thing was pretty pointless
It is not pointless, don't despise the intelligence of people that have thought about that before you :(.
It is fundamental for the Exception Handling, something I am working at the moment. FRAME:AUTO is pointless for anything useful concerning Exception Handling. If you can't fix it, leave it but I can't use UASM as it is for that.
FRAME will add the .pdata record, which is the default now even if you don't specify frame.. you can still use frame:<handler> if you need a custom one.
So what I'm saying is that you have full exception handling support built-in the prologue with all the pseudo-ops already, no need to add them manually.. unless you write a raw proc and have a specific requirement ?
I need a handler, there is no default handler, so I need FRAME:<handler>. Simply embedding the .pdarta and .xdata does not solve anything because the exception should be handled somewhere and it is not without a handler.

johnsa



exchdl proc FRAME pRecord:ptr EXCEPTION_RECORD64, ulframe:qword, pContext:ptr, x4:ptr
    add qword ptr [r8].CONTEXT.Rip_, 1  ;1=size of "in EAX, DX" opcode
    invoke printf, CStr("exception code: %X",10), [rcx].EXCEPTION_RECORD64.ExceptionCode
    mov eax, 0  ;0=continue execution?
    ret
exchdl endp

MyProc PROC FRAME:exchdl
.
; normal code
in eax, dx
.
MyProc ENDP



should work fine ? (without the need for pseudo ops)

nidud

#9
deleted

aw27

Quote from: johnsa on October 16, 2017, 10:00:58 PM
should work fine ? (without the need for pseudo ops)
I just wonder why something that was working fine in JWASM does not now, I mean the pseudocodes. I have not fully tested the FRAME:AUTO for Exception Handling, however if I need to produce code that works both in MASM and UASM with minor changes, it is much more difficult using the FRAME:AUTO. And everybody knows that UASM is MASM compatible, it does not remove features only adds features.
Anyway, the major problem is indeed "if UASM keeps using the ESP as frame pointer after I set EBP as frame pointer", the others may be worked around.


johnsa

I've updated the packages on the site dated today with all the fixes thus far, please test that out.

This works perfectly now for me:



option casemap:none

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
mov par1,rcx
mov par2,rdx
ret
proc1 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
    ret
mainE endp
end



nidud

#12
deleted

johnsa

That last one works for me:


D:\HJWasm\Tests>c:\jwasm\uasm64 -c -win64 -Zp8 exc.asm
UASM v2.42, Oct 16 2017, Masm-compatible assembler.
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.

exc.asm(2) : Warning A4095: Multiple .MODEL directives, .MODEL ignored
exc.asm: 28 lines, 3 passes, 1 ms, 1 warnings, 0 errors

D:\HJWasm\Tests>link /machine:x64 /subsystem:console exc.obj c:\jwasm\wininc\lib64\msvcrt.lib
Microsoft (R) Incremental Linker Version 14.10.25017.0
Copyright (C) Microsoft Corporation.  All rights reserved.


D:\HJWasm\Tests>exc
ExceptionHandler called

D:\HJWasm\Tests>



I've removed the need for frame:auto to generate the .endprolog
as long as the proc is a frame proc, it will be automatically inserted, which is why the first example warns about the manually added one.

aw27

I feel sorry, but a few things are not getting better, actually on the contrary.


option frame:NOAUTO

......

; Error A2256: .ENDPROLOG found before EH directives
proc1 proc FRAME
      db      048h
      push    rbp
      .pushreg rbp
      mov rbp, rsp
     .setframe rbp, 0
    .endprolog

    ret
proc1 endp