What's up ?

This may be a dumb question, but it's coming from a newbie.

Is it possible to link procadures with VC++ without using the PROC directive ?

I successfully linked the following proceadure with C++ using VC++ 6:

// C++ PART:

extern "C"
int __stdcall Sum(unsigned int a, unsigned int b);

int main() {

int a = Sum(3, 4);
cout << "Sum: " << a << endl;

return 0;


Sum proc a: DWORD, b: DWORD

mov eax, a
add eax, b

Sum endp

The above code works as expected. But for learning purposes I'd like NOT to
use MASM's PROC facility.
I'd like to declare the proceadure using only labels, and manipulating the stack
by hand. Something like this:


push ebp
mov epb, esp
; sub esp, 0

mov eax,
add eax, ; Does this work ?

mov esp, ebp
pop ebp

Is it possible ?

Thx in advance
Posted on 2003-08-20 01:05:29 by Waka
Hi, Waka

really, PROC is a macro, that does (in your case):
push ebp
mov epb, esp

so you can use with your current ASM (to disable this macro:

option prologue:none
option epilogue:none



or (should be the same, but shorter)

mov eax, [esp + 12 - DWORD]
add eax, [esp + 8 - DWORD]
Posted on 2003-08-20 02:35:28 by S.T.A.S.
Thanks, S.T.A.S.


mov eax, [esp + 12 - DWORD]
add eax, [esp + 8 - DWORD]

What does 'DWORD' mean in this case ?
I changed my previous code to that above, but now I can't link it to the C++ code,
it does assemble though

Thank you.
Posted on 2003-08-20 03:30:51 by Waka
DWORD = 4.

Who ever said a stack frame is needed?

pop edx
pop ecx
pop eax
add eax, ecx
push edx

Though the above code I cleared the stack

For some less destructive code:

mov eax, [esp+4]
add eax, [esp+8]

Hmm my code looks so much like S.T.A.S's.
Posted on 2003-08-20 08:44:23 by roticv

now I can't link it to the C++ code

well, i'm not good at linking with C code ;)
I just supposed if you can link to"Sum proc a: DWORD, b: DWORD", then you could link to that label.

may be this can help:

Syntax: PUBLIC name [, name]...


Makes one or more variables available to other modules in the
program. PUBLIC names can be forward referenced.

I still suggest to use:
option prologue:none

option epilogue:none

since this does enforce assembler don't generate stuff like:
push ebp
mov epb, esp
; sub esp, 0
and all labels that are inside proc are LOCAL by default, so you can avoid some bugs.

Syntax: OPTION PROLOGUE:macroname



PROLOGUE registers <macroname> as the macro function to be called
when a prologue needs to be generated. EPILOGUE registers
<macroname> as the macro procedure to be called when a RET or IRET
instruction is encountered.

You can revert to the default prologue or epilogue by specifying
PrologueDef or EpilogueDef as <macroname>. EPILOGUE code is

generated only if the RET or IRET instruction terminating the PROC
block has no operand. The RETN, RETF, and IRETF instructions do not
cause the assembler to generate epilogue code.

To suppress generation of the prologue or epilogue code, give NONE
as the <macroname>.

The assembler expects a macro definition of this form:

macroname MACRO procname, flags, argbytes, localbytes, <reglist>,

Parameter Description

procname Macro name for the procedure or NONE.

flags Word-size bit flag: (1=On, 0=Off)
Bits Description
0-2 Language type:
000 Not specified
001 C
100 Pascal
101 Fortran

110 Basic
111 Reserved
3 Reserved
4 Caller restores stack
5 FAR procedure
6 PRIVATE procedure
7 EXPORT procedure
8 Epilogue caused by IRET instruction

All other bits are reserved for future use.

argbytes The total number of bytes used by PROC arguments.

localbytes The total number of bytes used by variables defined
with the LOCAL directive inside the PROC block.

reglist Comma-delimited list of registers from the PROC
directive USE option. This list is reversed in
in the EPILOGUE directive. Angle brackets are

userparms Passed the optional macroarglist from the PROC

her is example of macros i'm using (I don't like use EBP for stack frame, because it can be another free register for use in asm):

sPrologue MACRO procname, flags, argbytes, localbytes, reglist,userparms:VARARG
ifnb reglist ;if there are registers to be saved, store them
for r,reglist
push r ;dont forget optimize: mov [esp...], : sub esp,vars
if localbytes NE 0
sub esp, localbytes ; make space on the stack for locals
; LocBytes equ localbytes ;these bytes are reserved for local vars on the stack
exitm <localbytes>

sEpilogue MACRO procname, flags, argbytes, localbytes, reglist,userparms:VARARG
if localbytes NE 0
add esp,localbytes ;; free space on the stack for locals
ifnb reglist ;; Pop off the registers -- they are in
for r,reglist ;; inverse order from the prologue call
pop r
ret argbytes

What does 'DWORD' mean in this case ?

"push ebp" does this:
1. moves value of EBP to address
2. subtracts from ESP SizeOf(DWORD)
3. adds to EIP SizeOf("push ebp" opcode)

so if we use ESP instead of EBP wee need to balance the stack "by hands" but it saves some bytes for us ;)

Hmm my code looks so much like S.T.A.S's.

so does mine:

pop edx
pop ecx
pop eax
add eax, ecx
jmp edx

Posted on 2003-08-20 09:35:23 by S.T.A.S.
some quicker one

mov eax, [esp+8]
add eax, [esp+4]
mov ecx, [esp]
;mov ebx, [esp] :(
add esp, 3*DWORD
jmp eCx
Posted on 2003-08-20 09:44:27 by S.T.A.S.
Bad for linking to VC++ because the compiler requires EBX (plus ESI, EDI, and EBP) to be preserved.
Use ECX or EDX instead of EBX.
Posted on 2003-08-20 22:06:20 by tenkey
Thanks, tenkey!
Posted on 2003-08-20 22:30:11 by S.T.A.S.
Hey, guys !

Thanks for answering.

But, my initial problem was to make VC++ 'see' the
proceadure label. How can I make MASM labels and variables
available to be used on VC++ ?

BTW, I didn't understand your macros, S.T.A.S. Thanks for
your comprehensive post anyway. Do you know a good reference
for me to learn to use macros ? A tutorial perhaps ? (besides
MASM manual).

My intention now is to replace some parts of a program
I made in C with ASM, to see if I can make it faster and
to learn how it's done.

Posted on 2003-08-20 22:42:05 by Waka
In C++ mode, extern "C" __stdcall in VC will generate a link name which is "_" + function-name + "@" + number-of-argument-bytes. The number of argument bytes is in decimal.

In your example, the linker will see that VC wants to link to _Sum@8.

If you use PUBLIC or EXTERNDEF, the name you use will probably be Sum@8 or _Sum@8.

Since you specify stdcall in the C code, you will eat up stack space if your function is called from a loop. Use ret 8 to delete the 8 bytes of argument from the stack.
Posted on 2003-08-20 23:35:01 by tenkey

I successfully linked the ... procedure with C++ using VC++ 6

Doesn't this works?
option prologue:none

option epilogue:none

I'm not good at the theory.
I just know that EXTERN/EXTERNDEF make asm "see" C labels :)
and I hope that PUBLIC will make your label "visible" for link.exe

Problem may be with exporting/importing of labels, since ms link uses
_imp__SomeFunc@N or _SomeFunc@N instead of SomeFuncI (N = bytes of parameters on the stack)
take a look inside .obj files, sure you'll find the answer

I've experiensed problems with linking my asm files a while ago, but found the solution and forgot it :(
Posted on 2003-08-20 23:37:25 by S.T.A.S.
I did this:

_Test: ; do nothing


or this:

_Test LABEL DWORD ; do nothing


But looking inside the obj file, I don't see the label.
How can even another asm file "see" the label if it's not inside
the obj file ?

Doesn't this works?

Doesn't this works?
option prologue:none
option epilogue:none

This does work, but I would like to it using only labels.
And I would like to have access to the global variables of the ASM file also.

Thanks once more !
Posted on 2003-08-21 00:23:13 by Waka

But looking inside the obj file, I don't see the label.
How can even another asm file "see" the label if it's not inside
the obj file ?

IMHO compiler did some optimization ;)

does PUBLIC label works or not? this should...

really in asm there are some ways to define label:
1. dummy label dword
2. dummy equ $
3. proc dummy (this will generate stuff like mov ebp, esp until you spacify option prologue:none
Posted on 2003-08-21 01:35:28 by S.T.A.S.