News:

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

Main Menu

OPTION LITERALS:ON and more than 2 varargs

Started by aw27, October 12, 2017, 01:45:21 AM

Previous topic - Next topic

aw27

With OPTION LITERALS:ON, more than 2 arguments in functions with VARARG produce a General failure even when the benefits of the option are not taken.


option frame:auto
OPTION LITERALS:ON

includelib \masm32\lib64\msvcrt.lib
printf proto :ptr, :vararg

.data
fmtstr1 db "val1=%d, val2=%d, val3=%d, val4=%d",10
fmtstr2 db "val1=%d, val2=%d, val3=%d",10
fmtstr3 db "val1=%d, val2=%d",10

.code

main proc
; These don't assemble:
;INVOKE printf, "val1=%d, val2=%d, val3=%d, val4=%d", 1,2,3,4
;INVOKE printf, "val1=%d, val2=%d, val3=%d", 1,2,3
; This assembles:
INVOKE printf, "val1=%d, val2=%d", 1,2

; These don't assemble:
;INVOKE printf, offset fmtstr1, 1,2,3,4
;INVOKE printf, offset fmtstr2, 1,2,3
; This assembles:
INVOKE printf, offset fmtstr3, 1,2

ret
main endp

end main



johnsa

This is fixed now, however there were two small other issues:

The format strings in .data were missing null terminator, and because there is no CRT startup you can't just ret from main so added ExitProcess to do a clean return.


option frame:auto
OPTION LITERALS:ON

includelib C:\jwasm\wininc\Lib64\msvcrt.lib
includelib kernel32.lib
ExitProcess proto :dword
printf proto :ptr, :vararg

.data
fmtstr1 db "val1=%d, val2=%d, val3=%d, val4=%d ",10,0
fmtstr2 db "val1=%d, val2=%d, val3=%d ",10,0
fmtstr3 db "val1=%d, val2=%d ",10,0

.code

main proc
; These don't assemble:
INVOKE printf, "val1=%d, val2=%d, val3=%d, val4=%d\n", 1,2,3,4
INVOKE printf, "val1=%d, val2=%d, val3=%d\n", 1,2,3
; This assembles:
INVOKE printf, "val1=%d, val2=%d\n", 1,2

; These don't assemble:
INVOKE printf, addr fmtstr1, 1,2,3,4
INVOKE printf, offset fmtstr2, 1,2,3
; This assembles:
INVOKE printf, addr fmtstr3, 1,2

invoke ExitProcess,0
main endp

end main


now produces output:


val1=1, val2=2, val3=3, val4=4
val1=1, val2=2, val3=3
val1=1, val2=2
val1=1, val2=2, val3=3, val4=4
val1=1, val2=2, val3=3
val1=1, val2=2


aw27

Quote from: johnsa on October 12, 2017, 10:24:54 PM
and because there is no CRT startup you can't just ret from main so added ExitProcess to do a clean return.
In single threaded application it is fine. RET returns and calls RtlExitUserThread which will end calling the RtlExitUserProcess, etc. However, I use RET mostly because it helps trap stack mismatch bugs, which are "fixed" by the ExitProcess call. Look at the example below and imagine what would happen with RET.


.data
fmt db "Hello",10,0

.code
main proc
sub rsp, 20h
mov rcx, offset fmt
call printf
        mov rcx,0
call ExitProcess
;ret

main endp


johnsa

I would agree, it used to be fine for me however when I seem to do that now the ret goes off into no mans land.. even though the stack is matched:

on entry: RSP = 00000018D92FFEF8
at the ret:  RSP = 00000018D92FFEF8

and off it goes into dead space and the app hangs for about 2 min before exiting.. not sure if this is a Windows 10 thing..

aw27

Quote from: johnsa on October 12, 2017, 11:18:20 PM
I would agree, it used to be fine for me however when I seem to do that now the ret goes off into no mans land.. even though the stack is matched:

on entry: RSP = 00000018D92FFEF8
at the ret:  RSP = 00000018D92FFEF8

and off it goes into dead space and the app hangs for about 2 min before exiting.. not sure if this is a Windows 10 thing..
Yes, it looks like it is a Windows 10 thing.  :(
I exited with Ctrl-C  :badgrin:

johnsa

The fun of Windows :)

Two more things to fix tonight and 2.42 should be ready for a test run.