News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

Half C, half stdcall

Started by jj2007, August 04, 2014, 09:33:46 AM

Previous topic - Next topic

jj2007

Playing with a hybrid of C and stdcall:

Switch$ MACRO src$
  ctCs$=0
  push reparg(src$)      ; three args are needed but ...
  push len([esp])        ; ... we push two of them here
  ifndef SwProc
      .if 0
            SwProc:
            push esi
            push edi
            push ecx
            mov esi, [esp+12+12]     ; switch arg
            mov ecx, [esp+12+8]      ; switch arg len
            mov edi, [esp+12+4]      ; case arg
            ; could be szCmp etc, but let's keep it simple:
            repe cmpsb      ; !Zero? means not equal
            .if Zero?
                  test byte ptr [edi], -1
            .endif
            pop ecx
            pop edi
            pop esi
            retn 4
      .endif
  endif
  xor ecx, ecx
ENDM

Case$ MACRO cmp$
  if ctCs$
      .else
  endif
  ctCs$=ctCs$+1
  push reparg(cmp$)      ; only one arg pushed here
  call SwProc
  .if Zero?
ENDM


Usage:

include \masm32\include\masm32rt.inc
include Switch$.inc
.code
start:
      mov esi, chr$("Test")
      mov edi, chr$("This is edi")

      Switch$ esi
      Case$ "Mist"
            print "found Mist"
      Case$ edi
            print "found edi"
      Case$ "Tes"
            print "found Tes"
      Case$ "Test"
            print "found Test"
      Case$ "Testx"
            print "found TestX"
      Else$
            print "found something else"
      Endsw$

      inkey chr$(13, 10, "OK")
      exit
end start

Gunther

Jochen,

runs fine under Windows 7-64:
Quote
found Test
OK

But the only time advantage would be the FASTCALL.

Gunther
You have to know the facts before you can distort them.

Siekmanski

Creative coders use backward thinking techniques as a strategy.

jj2007

Thanks for testing, Gunther and Marinus :icon14:

How would you do it with fastcall?

qWord

I  don't think that a register calling convention would speed this code, because of the limited number of available register under x86-32.
Even if it is a bit off topic, but what about creating a hash table while assembling? I've played with that in the past and found that you can get good results, but  it sometimes requires manual fine-tuning.
MREAL macros - when you need floating point arithmetic while assembling!

jj2007

Quote from: qWord on August 05, 2014, 10:44:02 AMwhat about creating a hash table while assembling?

How would that work with e.g. Case$ edi ?

My basic point here was to demonstrate the "hybrid" calling convention:
- push two (or more) args in "C mode"
- repeatedly push one (or more) args for use with a stdcall proc
- which picks the two args from stack
- finally, correct the stack, as the C calling convention does

Not really revolutionary, not really faster, but it saves a bit of code because you have to push only one Case$ argument in the Case$ macro.

Gunther

Jochen,

Quote from: jj2007 on August 05, 2014, 10:20:07 AM
How would you do it with fastcall?

that's indeed a bit difficult in your case. FASTCALL isn't been standardized, and is implemented differently, depending on the compiler vendor. Here is a good overview.

Gunther
You have to know the facts before you can distort them.

qWord

Quote from: jj2007 on August 05, 2014, 04:13:26 PMHow would that work with e.g. Case$ edi ?
that won't work of course.
MREAL macros - when you need floating point arithmetic while assembling!

hutch--

The problem with combining C and STDCALL is the near RET instruction (C3) will only take an immediate to balance the stack, this is why the C calling convention corrects ESP after the RET have returned.

The easiest way to pass a variable number of arguments is in a structure, one argument as the address of the structure, balance the stack with a RET 4 and access as many arguments as you like, I imagine this is why its so popular with C/C++ compilers. You can easily make a structure that has as many members as you like and you just fill in the member names you want before you make the call passing the structure address. Be cheeky and pass the structure address in EAX and you have no stack to balance at all.  :biggrin:

Gunther

Quote from: hutch-- on August 26, 2014, 02:37:11 AM
Be cheeky and pass the structure address in EAX and you have no stack to balance at all.  :biggrin:

That's indeed very cheeky and clever.  :t

Gunther
You have to know the facts before you can distort them.

jj2007

Quote from: hutch-- on August 26, 2014, 02:37:11 AMBe cheeky and pass the structure address in EAX and you have no stack to balance at all.  :biggrin:

I pass the address of the structure in esp:

Case$ MACRO cmp$
  ..
  call SwProc