News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

What does MASM's proc expand to?

Started by nixeagle, May 02, 2012, 06:43:06 PM

Previous topic - Next topic

nixeagle

I'm getting lots of segfaults when returning from procedures in a loop. I have something like:


timeit proc
   ...
   push eax
   push edx
   call printer
   ret
timeit endp

printer proc
   pop edx
   pop eax
   ...
   ret
printer endp


Is MASM doing something behind my back in these proc definitions? Maybe I'm being dumb, but is there a manual for MASM similar to what NASM has? http://www.posix.nl/linuxassembly/nasmdochtml/nasmdoc0.html

dedndave

what you want may be a macro, rather than a proc

when you call a proc, the return address is pushed onto the stack,
which displaces the values you are trying to store and recover

if you are trying to pass parameters - the assembler will set up a stack frame for you and use EBP to access them
you can avoid the stack frame overhead by using OPTION directives

if you want to use INVOKE to pass parameters...
first - define a prototype - this generally appears at the beginning of the source
it tells the assembler how many and what size that parameters are
printer PROTO :DWORD,:DWORD

then, you can invoke the call
        INVOKE  printer,Parm1,Parm2
or, in your case maybe
        INVOKE  printer,edx,eax

and the proc might start out like this...
printer PROC Parm1:DWORD,Parm2:DWORD

        mov     edx,Parm1
        mov     eax,Parm2


the assembler generates code like this
        push    ebp
        mov     ebp,esp
        mov     edx,[ebp+8]
        mov     eax,[ebp+12]


inside that proc, whereever you have a RET, it generates something like this
        leave           ;same as mov esp,ebp - pop ebp
        ret     8       ;return and discard the 2 dword parameters

jj2007

Check Masm Programmer's Guide - the link is still active.
Re proc, search in the guide for PROLOGUE and EPILOGUE. Afterwards, put an int 3 before the call, and see what Olly has to tell you. The learning curve seems steep, but in reality you just hit F7, and Olly shows you exactly what your code does.

My signature is also a concise collection of tips, tricks, and, well, traps :bg

nixeagle

Quote from: dedndave on May 02, 2012, 07:17:09 PM
what you want may be a macro, rather than a proc

when you call a proc, the return address is pushed onto the stack,
which displaces the values you are trying to store and recover

Doh! :red This explains it.

Quote from: jj2007 on May 02, 2012, 07:20:03 PM
Check Masm Programmer's Guide - the link is still active.
Re proc, search in the guide for PROLOGUE and EPILOGUE. Afterwards, put an int 3 before the call, and see what Olly has to tell you. The learning curve seems steep, but in reality you just hit F7, and Olly shows you exactly what your code does.

My signature is also a concise collection of tips, tricks, and, well, traps :bg


Thanks! :U

Now maybe between these two I'll be able to finish my translation. Dunno why I thought masm was doing something special :/. Brainfarts suck :(.

nixeagle

Yey! :bg Properly popping and pushing esp solves everything :D.

I also changed from MFENCE to CPUID as MASM did not recognize the former. As I don't know which directive to toggle to get it to recognize it, I just left it for now :lol. Now just to adjust the C++ program to also do the same and I think the MASM and C++ program will be functionally equivalent. I'm going to maintain the C++ version alongside the MASM program.

Has been a long time since I've attempted a pure assembly program. I usually work with just one or two inline functions :eek.

Now just to RTFM on how to get MASM to repeat things such as a section of memory initialized to 0 for use with the tallying stuff and I'll be ready to post my first draft in the other thread :dance:.

dedndave

        INCLUDE \masm32\include\masm32rt.inc
        .586
        .MMX
        .XMM


order is important   :P

nixeagle

Quote from: dedndave on May 02, 2012, 08:04:25 PM
        INCLUDE \masm32\include\masm32rt.inc
        .586
        .MMX
        .XMM


order is important   :P

Thanks, I'll remember this for later if I happen to need MFENCE or something else. For now working on affinity and priority. Plus I had to pull my debugger (gdb) out  :(.

dedndave

the problem i have with CPUID is - it's wobbly - lol
i think it may take as much as +/- 5 cycles each time you call it
RDTSC might be the same way

it may well be that it is wobbly because it is serializing a different cache of instructions each time
it's a little bit like trying to measure a molecule with a yardstick

nixeagle

Quote from: dedndave on May 02, 2012, 09:04:54 PM
the problem i have with CPUID is - it's wobbly - lol
i think it may take as much as +/- 5 cycles each time you call it
RDTSC might be the same way

it may well be that it is wobbly because it is serializing a different cache of instructions each time
it's a little bit like trying to measure a molecule with a yardstick

Well we can try MFENCE too. I'm just picking my battles with the MASM language/assembler. Speaking of that, I've managed to get process priority working. Doing so actually allows the CPU to spin up correctly :8).



Still a fair number of outliers... plus some runs even manage to complete much faster than the average. :eek I'm thinking those will clear out a bit once I figure affinity out. :bg.

P.S. What is really weird about all of this... is leaving the CPU in a lower power state gives more consistent timings then when we spin it up. At least so far, I won't know if this is true no matter what until I play with the spun up CPU some more.

P.P.S. I forgot to include a few (interesting to me) numbers :D

SDev->37.5219
Mean->100.234
GeometricMean->96.6003
HarmonicMean->94.1056
Median->88
Mode->{85}
MeanDeviation->22.3815
Min->54
Max->12681
Skewness->69.0209
Length->1000001
TrimmedMean->95.6781
MeanDeviation->22.3815
QuartileDeviation->1.5
InterquartileRange->3}



MichaelW

eschew obfuscation

hutch--

Keep this in mind, when you use PROC in MASM, you are telling MASM to build a procedure WITH a stack frame. If you need it you can build a procedure with NO stack frame.


OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE

your PROC args etc ....

  ; your code goes here

your endp

OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef


It gives you full control over procedure entry and exit.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php

nixeagle

Quote from: hutch-- on May 03, 2012, 03:42:16 AM
Keep this in mind, when you use PROC in MASM, you are telling MASM to build a procedure WITH a stack frame. If you need it you can build a procedure with NO stack frame.


OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE

your PROC args etc ....

  ; your code goes here

your endp

OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef


It gives you full control over procedure entry and exit.

:clap: So I can make MASM act like NASM! This will be useful for some of the functions in the test program :)

hutch--

 :bg

MASM had this capacity in 1990, the main advantage is that you can both write procedures with no stack frame and use the INVOKE notation complete with its argument size and count checking. You will still need to write a prototype for your procedure but you get the best of both worlds using this technique.
Download site for MASM32      New MASM Forum
https://masm32.com          https://masm32.com/board/index.php