www.digitalmars.com         C & C++   DMDScript  

c++ - Calling assembly functions from C++.

reply Noob_programmer <Noob_programmer_member pathlink.com> writes:
I posted this in the 16-bit dos forum a few days ago and haven't recieved a
responce yet.  Maybe someone here can help me out.




hi,
I am trying to call an assembly function I made, from a c++ program.  I get an
error message from the DM compiler that states

diag01.obj(diag01)
Error 42: Symbol Undefined _memSize

--- errorlevel 1

I use the command:
dmc diag01.cpp -msd

But it creates an executable that seems to run.

Here is the assembly code:

Public _memSize

data

buffer1 BYTE 20 DUP(?)
count	DWORD 0

code

_memSize PROC NEAR, C
PUSH EBP
MOV EBX, 00000000h
MOV AX, SEG buffer1
MOV ES, AX
MOV AX, OFFSET buffer1
MOV DI, AX
L1:
MOV EAX, 0000E820h
MOV EDX, 534D4150h		;'SMAP'
MOV ECX, SIZEOF buffer1		
INT 15h
JC L2
CMP EBX, 0
JZ L2
MOV EAX, OFFSET buffer1 + 8
MOV ECX, [EAX]			;Dereference EAX
ADD count, ECX
JMP L1
L2:
POP EBP
RET	
_memSize ENDP

END


And here is the C++ code:

#include <iostream.h>
#include <stdlib.h>

extern "C" void memSize();

int main()
{
unsigned int choice;
unsigned long count = 0;
system ("CLS");
do
{
cout << "Choose something. ";
cin >> choice;
switch(choice)
{
case 1:   system ("CLS");
cout << "Option 1\n";
break;
case 2:   system ("CLS");
cout << "Option 2\n";
memSize();
break;
case 3:   system ("CLS");
cout << "Option 3\n";
break;
case 0:   system ("CLS");
cout << "Exiting!!!\n";
break;
default:  system ("CLS");
cout << "Not a valid selection, please re-choose!\n";
}
}while(choice != 0);
return 0;
}


Could someone please look at my code and tell me what I am doing wrong.

Also, could someone tell me how to return values from the assembly funtion back
to the C++ calling program.

Thanks

BTW: The assembly funtion finds the total system memory(conventional, reserved,
and extended).
Jun 13 2004
parent reply "Walter" <newshound digitalmars.com> writes:
You need to link in the object file that the assembler created.

"Noob_programmer" <Noob_programmer_member pathlink.com> wrote in message
news:caiv7b$1pnn$1 digitaldaemon.com...
 I posted this in the 16-bit dos forum a few days ago and haven't recieved
a
 responce yet.  Maybe someone here can help me out.




 hi,
 I am trying to call an assembly function I made, from a c++ program.  I
get an
 error message from the DM compiler that states

 diag01.obj(diag01)
 Error 42: Symbol Undefined _memSize

 --- errorlevel 1

 I use the command:
 dmc diag01.cpp -msd

 But it creates an executable that seems to run.

 Here is the assembly code:

 Public _memSize

 data

 buffer1 BYTE 20 DUP(?)
 count DWORD 0

 code

 _memSize PROC NEAR, C
 PUSH EBP
 MOV EBX, 00000000h
 MOV AX, SEG buffer1
 MOV ES, AX
 MOV AX, OFFSET buffer1
 MOV DI, AX
 L1:
 MOV EAX, 0000E820h
 MOV EDX, 534D4150h ;'SMAP'
 MOV ECX, SIZEOF buffer1
 INT 15h
 JC L2
 CMP EBX, 0
 JZ L2
 MOV EAX, OFFSET buffer1 + 8
 MOV ECX, [EAX] ;Dereference EAX
 ADD count, ECX
 JMP L1
 L2:
 POP EBP
 RET
 _memSize ENDP

 END


 And here is the C++ code:

 #include <iostream.h>
 #include <stdlib.h>

 extern "C" void memSize();

 int main()
 {
 unsigned int choice;
 unsigned long count = 0;
 system ("CLS");
 do
 {
 cout << "Choose something. ";
 cin >> choice;
 switch(choice)
 {
 case 1:   system ("CLS");
 cout << "Option 1\n";
 break;
 case 2:   system ("CLS");
 cout << "Option 2\n";
 memSize();
 break;
 case 3:   system ("CLS");
 cout << "Option 3\n";
 break;
 case 0:   system ("CLS");
 cout << "Exiting!!!\n";
 break;
 default:  system ("CLS");
 cout << "Not a valid selection, please re-choose!\n";
 }
 }while(choice != 0);
 return 0;
 }


 Could someone please look at my code and tell me what I am doing wrong.

 Also, could someone tell me how to return values from the assembly funtion
back
 to the C++ calling program.

 Thanks

 BTW: The assembly funtion finds the total system memory(conventional,
reserved,
 and extended).
Jun 13 2004
next sibling parent reply Noob_programmer <Noob_programmer_member pathlink.com> writes:
It is still doing the same thing, here is the output.

C:\dm\bin>dmc diag01.cpp memSize.obj -msd
diag01.cpp:
link diag01+memSize/noi;
OPTLINK (R) for Win32  Release 7.50B1
Copyright (C) Digital Mars 1989 - 2001  All Rights Reserved

diag01.obj(diag01)
Error 42: Symbol Undefined _memSize

--- errorlevel 1


The linker doesn't seem to be finding it.  Any other suggestions?




In article <caj1ij$1sut$2 digitaldaemon.com>, Walter says...
You need to link in the object file that the assembler created.

"Noob_programmer" <Noob_programmer_member pathlink.com> wrote in message
news:caiv7b$1pnn$1 digitaldaemon.com...
 I posted this in the 16-bit dos forum a few days ago and haven't recieved
a
 responce yet.  Maybe someone here can help me out.




 hi,
 I am trying to call an assembly function I made, from a c++ program.  I
get an
 error message from the DM compiler that states

 diag01.obj(diag01)
 Error 42: Symbol Undefined _memSize

 --- errorlevel 1

 I use the command:
 dmc diag01.cpp -msd

 But it creates an executable that seems to run.

 Here is the assembly code:

 Public _memSize

 data

 buffer1 BYTE 20 DUP(?)
 count DWORD 0

 code

 _memSize PROC NEAR, C
 PUSH EBP
 MOV EBX, 00000000h
 MOV AX, SEG buffer1
 MOV ES, AX
 MOV AX, OFFSET buffer1
 MOV DI, AX
 L1:
 MOV EAX, 0000E820h
 MOV EDX, 534D4150h ;'SMAP'
 MOV ECX, SIZEOF buffer1
 INT 15h
 JC L2
 CMP EBX, 0
 JZ L2
 MOV EAX, OFFSET buffer1 + 8
 MOV ECX, [EAX] ;Dereference EAX
 ADD count, ECX
 JMP L1
 L2:
 POP EBP
 RET
 _memSize ENDP

 END


 And here is the C++ code:

 #include <iostream.h>
 #include <stdlib.h>

 extern "C" void memSize();

 int main()
 {
 unsigned int choice;
 unsigned long count = 0;
 system ("CLS");
 do
 {
 cout << "Choose something. ";
 cin >> choice;
 switch(choice)
 {
 case 1:   system ("CLS");
 cout << "Option 1\n";
 break;
 case 2:   system ("CLS");
 cout << "Option 2\n";
 memSize();
 break;
 case 3:   system ("CLS");
 cout << "Option 3\n";
 break;
 case 0:   system ("CLS");
 cout << "Exiting!!!\n";
 break;
 default:  system ("CLS");
 cout << "Not a valid selection, please re-choose!\n";
 }
 }while(choice != 0);
 return 0;
 }


 Could someone please look at my code and tell me what I am doing wrong.

 Also, could someone tell me how to return values from the assembly funtion
back
 to the C++ calling program.

 Thanks

 BTW: The assembly funtion finds the total system memory(conventional,
reserved,
 and extended).
Jun 15 2004
parent reply "Walter" <newshound digitalmars.com> writes:
"Noob_programmer" <Noob_programmer_member pathlink.com> wrote in message
news:cana79$2lnv$1 digitaldaemon.com...
 It is still doing the same thing, here is the output.

 C:\dm\bin>dmc diag01.cpp memSize.obj -msd
 diag01.cpp:
 link diag01+memSize/noi;
 OPTLINK (R) for Win32  Release 7.50B1
 Copyright (C) Digital Mars 1989 - 2001  All Rights Reserved

 diag01.obj(diag01)
 Error 42: Symbol Undefined _memSize

 --- errorlevel 1


 The linker doesn't seem to be finding it.  Any other suggestions?
Run obj2asm on your memSize.obj and have a look to see if _memSize is in it.
Jun 15 2004
parent reply Noob_programmer <Noob_programmer_member pathlink.com> writes:
I was talking to a friend and he told me that MASM provides the _'s during
assembly and that they are un-neccessary in the source code.  So I followed his
suggestion and low and behold it worked.

I am encountering another problem as well now.  I am writing a program in C++
using the Digital Mars compiler that calls a procedure I wrote in assembly.  The
procedure totals the total memory size(conventional, reserved, and extended),
places the total in EAX and returns to the C++ calling program.  
When I run the procedure seperatly, it works fine.  When I run the C++ program
that calls the procedure, it diesn't work.
This is the command I throw the DM compiler

 dmc diag01.cpp memSize.asm -msd
This is the updated assembly code: PUBLIC memSize MODEL SMALL, C 386 data buffer1 BYTE 20 DUP(?) count DWORD 0 code memSize PROC NEAR PUSH EBP MOV EBX, 00000000h MOV AX, SEG buffer1 MOV ES, AX MOV AX, OFFSET buffer1 MOV DI, AX L1: MOV EAX, 0000E820h MOV EDX, 534D4150h ;'SMAP' MOV ECX, SIZEOF buffer1 INT 15h JC L2 CMP EBX, 0 JZ L2 MOV EAX, OFFSET buffer1 + 8 MOV ECX, [EAX] ADD count, ECX JMP L1 L2: MOV EAX, count POP EBP RET memSize ENDP END This is the C++ code: #include <iostream.h> #include <stdlib.h> extern "C" void memSize(); int main() { unsigned int choice; unsigned long count = 0; system ("CLS"); do { cout << "Choose something. "; cin >> choice; switch(choice) { case 1: system ("CLS"); cout << "Option 1\n"; break; case 2: system ("CLS"); cout << "Option 2\n"; memSize(); _asm { MOV count, EAX } cout << count << endl; break; case 3: system ("CLS"); cout << "Option 3\n"; break; case 0: system ("CLS"); cout << "Exiting!!!\n"; break; default: system ("CLS"); cout << "Not a valid selection, please re-choose!\n"; } }while(choice != 0); return 0; } When I run the program, it outputs 0. 0 is the original value I initalize count with in the beginning of the assembly code(I tested to see if the code modifies the value by placing different values in count and the program outputs the value I place in it). This is telling me that the assembly code isn't modifing the value. If anyone can give me any suggestions, I would appreiciate it. I am starting to go CRAZY!!!!! In article <canegb$2s9j$2 digitaldaemon.com>, Walter says...
"Noob_programmer" <Noob_programmer_member pathlink.com> wrote in message
news:cana79$2lnv$1 digitaldaemon.com...
 It is still doing the same thing, here is the output.

 C:\dm\bin>dmc diag01.cpp memSize.obj -msd
 diag01.cpp:
 link diag01+memSize/noi;
 OPTLINK (R) for Win32  Release 7.50B1
 Copyright (C) Digital Mars 1989 - 2001  All Rights Reserved

 diag01.obj(diag01)
 Error 42: Symbol Undefined _memSize

 --- errorlevel 1


 The linker doesn't seem to be finding it.  Any other suggestions?
Run obj2asm on your memSize.obj and have a look to see if _memSize is in it.
Jun 18 2004
next sibling parent "Walter" <newshound digitalmars.com> writes:
A couple things. First, you can just do:
    count = memSize();
Second, when you can't figure out why a program isn't working, simplify,
simplify, simplify. For example, rewrite memSize() so it is just a:
    mov EAX,3
    ret
and get that to work. Iostreams is very complex. You don't need it in a
simplified program, it just confuses things, use printf instead.
Third, there seems to be some confusion as to whether your program is a 16
bit one or a 32 bit one, i.e. the code mixes and matches 16 and 32 bit
addressing modes.
Lastly, obj2asm is your friend. I can't emphasize this enough. Obj2asm both
modules and go through the assembler listing of your simplified, simplified,
SIMPLIFIED code.

"Noob_programmer" <Noob_programmer_member pathlink.com> wrote in message
news:cauufa$1ug8$1 digitaldaemon.com...
 I was talking to a friend and he told me that MASM provides the _'s during
 assembly and that they are un-neccessary in the source code.  So I
followed his
 suggestion and low and behold it worked.

 I am encountering another problem as well now.  I am writing a program in
C++
 using the Digital Mars compiler that calls a procedure I wrote in
assembly. The
 procedure totals the total memory size(conventional, reserved, and
extended),
 places the total in EAX and returns to the C++ calling program.
 When I run the procedure seperatly, it works fine.  When I run the C++
program
 that calls the procedure, it diesn't work.
 This is the command I throw the DM compiler

 dmc diag01.cpp memSize.asm -msd
This is the updated assembly code: PUBLIC memSize MODEL SMALL, C 386 data buffer1 BYTE 20 DUP(?) count DWORD 0 code memSize PROC NEAR PUSH EBP MOV EBX, 00000000h MOV AX, SEG buffer1 MOV ES, AX MOV AX, OFFSET buffer1 MOV DI, AX L1: MOV EAX, 0000E820h MOV EDX, 534D4150h ;'SMAP' MOV ECX, SIZEOF buffer1 INT 15h JC L2 CMP EBX, 0 JZ L2 MOV EAX, OFFSET buffer1 + 8 MOV ECX, [EAX] ADD count, ECX JMP L1 L2: MOV EAX, count POP EBP RET memSize ENDP END This is the C++ code: #include <iostream.h> #include <stdlib.h> extern "C" void memSize(); int main() { unsigned int choice; unsigned long count = 0; system ("CLS"); do { cout << "Choose something. "; cin >> choice; switch(choice) { case 1: system ("CLS"); cout << "Option 1\n"; break; case 2: system ("CLS"); cout << "Option 2\n"; memSize(); _asm { MOV count, EAX } cout << count << endl; break; case 3: system ("CLS"); cout << "Option 3\n"; break; case 0: system ("CLS"); cout << "Exiting!!!\n"; break; default: system ("CLS"); cout << "Not a valid selection, please re-choose!\n"; } }while(choice != 0); return 0; } When I run the program, it outputs 0. 0 is the original value I initalize
count
 with in the beginning of the assembly code(I tested to see if the code
modifies
 the value by placing different values in count and the program outputs the
value
 I place in it).  This is telling me that the assembly code isn't modifing
the
 value.

 If anyone can give me any suggestions, I would appreiciate it.  I am
starting to
 go CRAZY!!!!!





 In article <canegb$2s9j$2 digitaldaemon.com>, Walter says...
"Noob_programmer" <Noob_programmer_member pathlink.com> wrote in message
news:cana79$2lnv$1 digitaldaemon.com...
 It is still doing the same thing, here is the output.

 C:\dm\bin>dmc diag01.cpp memSize.obj -msd
 diag01.cpp:
 link diag01+memSize/noi;
 OPTLINK (R) for Win32  Release 7.50B1
 Copyright (C) Digital Mars 1989 - 2001  All Rights Reserved

 diag01.obj(diag01)
 Error 42: Symbol Undefined _memSize

 --- errorlevel 1


 The linker doesn't seem to be finding it.  Any other suggestions?
Run obj2asm on your memSize.obj and have a look to see if _memSize is in
it.

Jun 18 2004
prev sibling next sibling parent Mark Junker <mjscod gmx.de> writes:
Noob_programmer schrieb:

 I was talking to a friend and he told me that MASM provides the _'s during
 assembly and that they are un-neccessary in the source code.  So I followed his
 suggestion and low and behold it worked.
Thats the defined behaviour when you use the function language specifier "C".
 I am encountering another problem as well now.  I am writing a program in C++
 using the Digital Mars compiler that calls a procedure I wrote in assembly. 
The
 procedure totals the total memory size(conventional, reserved, and extended),
 places the total in EAX and returns to the C++ calling program.  
 When I run the procedure seperatly, it works fine.  When I run the C++ program
 that calls the procedure, it diesn't work.
 This is the command I throw the DM compiler
 
 
dmc diag01.cpp memSize.asm -msd
This is the updated assembly code: PUBLIC memSize MODEL SMALL, C 386 data buffer1 BYTE 20 DUP(?) count DWORD 0 code memSize PROC NEAR PUSH EBP MOV EBX, 00000000h MOV AX, SEG buffer1 MOV ES, AX
Please save ES before using it.
 MOV AX, OFFSET buffer1
 MOV DI, AX
Please save DI before using it.
 
 L1:
 
 MOV EAX, 0000E820h
 MOV EDX, 534D4150h		;'SMAP'
 MOV ECX, SIZEOF buffer1		
 INT 15h
 JC L2
 CMP EBX, 0
test ebx, ebx
 JZ L2
 MOV EAX, OFFSET buffer1 + 8
 MOV ECX, [EAX]			
Change the two lines above to: mov ecx, es:[di + 8]
 ADD count, ECX
 JMP L1
 
 L2:
 
 MOV EAX, count
Please return output in DX:AX, because ... -> see comment in c++ source.
 POP EBP
 RET	
 memSize ENDP
 
 END
 
 This is the C++ code:
 
 #include <iostream.h>
 #include <stdlib.h>
 
 extern "C" void memSize();
Specify as: extern "C" long memSize(void);
 
 int main()
 {
 unsigned int choice;
 unsigned long count = 0;
 system ("CLS");
 do
 {
 cout << "Choose something. ";
 cin >> choice;
 switch(choice)
 {
 case 1:   system ("CLS");
 cout << "Option 1\n";
 break;
 case 2:   system ("CLS");
 cout << "Option 2\n";
 memSize();
 _asm
 {
 MOV count, EAX
 }
Don't use inline assembler at this point because you cannot know how many assembler instructions will be inserted by the compiler between the function call and the inline assembler block.
 cout << count << endl;
 break;
 case 3:   system ("CLS");
 cout << "Option 3\n";
 break;
 case 0:   system ("CLS");
 cout << "Exiting!!!\n";
 break;
 default:  system ("CLS");
 cout << "Not a valid selection, please re-choose!\n";
 }
 }while(choice != 0);
 return 0;
 }
 
 
 When I run the program, it outputs 0.  0 is the original value I initalize
count
 with in the beginning of the assembly code(I tested to see if the code modifies
 the value by placing different values in count and the program outputs the
value
 I place in it).  This is telling me that the assembly code isn't modifing the
 value.  
 
 If anyone can give me any suggestions, I would appreiciate it.  I am starting
to
 go CRAZY!!!!!
Is this function really supported by your BIOS? Maybe you can try another function to find out how many memory is installed in your system ... Anyway, below is my memSize function. Might be usefull for you. Compile with: dmc -3 -msd test.cpp #pragma pack(push,1) struct TMemoryMap { unsigned long ulBaseLo, ulBaseHi; unsigned long ulLengthLo, ulLengthHi; unsigned long ulType; }; #pragma pack(pop) extern "C" static long memSize(void) { unsigned long ulSize = 0; TMemoryMap Buffer; bool bDidFail; long lNextValue = 0; do { int iFlags = 0; long lEAX = 0, lEBX = 0; __asm { mov ebx, lNextValue push di push es push ss pop es lea di, Buffer mov eax, 0xE820 mov edx, 0x534d4150 mov ecx, sizeof(Buffer) int 0x15 pop es pop di pushf pop iFlags mov lEAX, eax mov lEBX, ebx } // print INT function status information printf("%04x, %08lx, %08lx\n", iFlags, lEAX, lEBX); // check for CF && EAX=="SMAP" bDidFail = (iFlags & 1) || (lEAX!=0x534d4150); if (!bDidFail) { ulSize += Buffer.ulLengthLo; lNextValue = lEBX; // continuation value } // print more status information printf("%d / %08lx / %08lx\n", (int) bDidFail, ulSize, lNextValue); } while (!bDidFail && lNextValue!=0); return ulSize; } Regards, Mark
Jun 18 2004
prev sibling parent Mark Junker <mjscod gmx.de> writes:
Noob_programmer schrieb:

 I was talking to a friend and he told me that MASM provides the _'s during
 assembly and that they are un-neccessary in the source code.  So I followed his
 suggestion and low and behold it worked.
Thats the defined behaviour when you use the function language specifier "C".
 I am encountering another problem as well now.  I am writing a program in C++
 using the Digital Mars compiler that calls a procedure I wrote in assembly. 
The
 procedure totals the total memory size(conventional, reserved, and extended),
 places the total in EAX and returns to the C++ calling program.  
 When I run the procedure seperatly, it works fine.  When I run the C++ program
 that calls the procedure, it diesn't work.
 This is the command I throw the DM compiler
 
 
dmc diag01.cpp memSize.asm -msd
This is the updated assembly code: PUBLIC memSize MODEL SMALL, C 386 data buffer1 BYTE 20 DUP(?) count DWORD 0 code memSize PROC NEAR PUSH EBP MOV EBX, 00000000h MOV AX, SEG buffer1 MOV ES, AX
Please save ES before using it.
 MOV AX, OFFSET buffer1
 MOV DI, AX
Please save DI before using it.
 
 L1:
 
 MOV EAX, 0000E820h
 MOV EDX, 534D4150h		;'SMAP'
 MOV ECX, SIZEOF buffer1		
 INT 15h
 JC L2
 CMP EBX, 0
test ebx, ebx
 JZ L2
 MOV EAX, OFFSET buffer1 + 8
 MOV ECX, [EAX]			
Change the two lines above to: mov ecx, es:[di + 8]
 ADD count, ECX
 JMP L1
 
 L2:
 
 MOV EAX, count
Please return output in DX:AX, because ... -> see comment in c++ source.
 POP EBP
 RET	
 memSize ENDP
 
 END
 
 This is the C++ code:
 
 #include <iostream.h>
 #include <stdlib.h>
 
 extern "C" void memSize();
Specify as: extern "C" long memSize(void);
 
 int main()
 {
 unsigned int choice;
 unsigned long count = 0;
 system ("CLS");
 do
 {
 cout << "Choose something. ";
 cin >> choice;
 switch(choice)
 {
 case 1:   system ("CLS");
 cout << "Option 1\n";
 break;
 case 2:   system ("CLS");
 cout << "Option 2\n";
 memSize();
 _asm
 {
 MOV count, EAX
 }
Don't use inline assembler at this point because you cannot know how many assembler instructions will be inserted by the compiler between the function call and the inline assembler block.
 cout << count << endl;
 break;
 case 3:   system ("CLS");
 cout << "Option 3\n";
 break;
 case 0:   system ("CLS");
 cout << "Exiting!!!\n";
 break;
 default:  system ("CLS");
 cout << "Not a valid selection, please re-choose!\n";
 }
 }while(choice != 0);
 return 0;
 }
 
 
 When I run the program, it outputs 0.  0 is the original value I initalize
count
 with in the beginning of the assembly code(I tested to see if the code modifies
 the value by placing different values in count and the program outputs the
value
 I place in it).  This is telling me that the assembly code isn't modifing the
 value.  
 
 If anyone can give me any suggestions, I would appreiciate it.  I am starting
to
 go CRAZY!!!!!
Is this function really supported by your BIOS? Maybe you can try another function to find out how many memory is installed in your system ... Anyway, below is my memSize function. Might be usefull for you. Compile with: dmc -3 -msd test.cpp #pragma pack(push,1) struct TMemoryMap { unsigned long ulBaseLo, ulBaseHi; unsigned long ulLengthLo, ulLengthHi; unsigned long ulType; }; #pragma pack(pop) extern "C" long memSize(void) { unsigned long ulSize = 0; TMemoryMap Buffer; bool bDidFail; long lNextValue = 0; do { int iFlags = 0; long lEAX = 0, lEBX = 0; __asm { mov ebx, lNextValue push di push es push ss pop es lea di, Buffer mov eax, 0xE820 mov edx, 0x534d4150 mov ecx, sizeof(Buffer) int 0x15 pop es pop di pushf pop iFlags mov lEAX, eax mov lEBX, ebx } // print INT function status information printf("%04x, %08lx, %08lx\n", iFlags, lEAX, lEBX); // check for CF && EAX=="SMAP" bDidFail = (iFlags & 1) || (lEAX!=0x534d4150); if (!bDidFail) { ulSize += Buffer.ulLengthLo; lNextValue = lEBX; // continuation value } // print more status information printf("%d / %08lx / %08lx\n", (int) bDidFail, ulSize, lNextValue); } while (!bDidFail && lNextValue!=0); return ulSize; } Regards, Mark
Jun 18 2004
prev sibling parent Noob_programmer <Noob_programmer_member pathlink.com> writes:
It is still doing the same thing, here is the output.

C:\dm\bin>dmc diag01.cpp memSize.obj -msd
diag01.cpp:
link diag01+memSize/noi;
OPTLINK (R) for Win32  Release 7.50B1
Copyright (C) Digital Mars 1989 - 2001  All Rights Reserved

diag01.obj(diag01)
Error 42: Symbol Undefined _memSize

--- errorlevel 1


The linker doesn't seem to be finding it.  Any other suggestions?




In article <caj1ij$1sut$2 digitaldaemon.com>, Walter says...
You need to link in the object file that the assembler created.

"Noob_programmer" <Noob_programmer_member pathlink.com> wrote in message
news:caiv7b$1pnn$1 digitaldaemon.com...
 I posted this in the 16-bit dos forum a few days ago and haven't recieved
a
 responce yet.  Maybe someone here can help me out.




 hi,
 I am trying to call an assembly function I made, from a c++ program.  I
get an
 error message from the DM compiler that states

 diag01.obj(diag01)
 Error 42: Symbol Undefined _memSize

 --- errorlevel 1

 I use the command:
 dmc diag01.cpp -msd

 But it creates an executable that seems to run.

 Here is the assembly code:

 Public _memSize

 data

 buffer1 BYTE 20 DUP(?)
 count DWORD 0

 code

 _memSize PROC NEAR, C
 PUSH EBP
 MOV EBX, 00000000h
 MOV AX, SEG buffer1
 MOV ES, AX
 MOV AX, OFFSET buffer1
 MOV DI, AX
 L1:
 MOV EAX, 0000E820h
 MOV EDX, 534D4150h ;'SMAP'
 MOV ECX, SIZEOF buffer1
 INT 15h
 JC L2
 CMP EBX, 0
 JZ L2
 MOV EAX, OFFSET buffer1 + 8
 MOV ECX, [EAX] ;Dereference EAX
 ADD count, ECX
 JMP L1
 L2:
 POP EBP
 RET
 _memSize ENDP

 END


 And here is the C++ code:

 #include <iostream.h>
 #include <stdlib.h>

 extern "C" void memSize();

 int main()
 {
 unsigned int choice;
 unsigned long count = 0;
 system ("CLS");
 do
 {
 cout << "Choose something. ";
 cin >> choice;
 switch(choice)
 {
 case 1:   system ("CLS");
 cout << "Option 1\n";
 break;
 case 2:   system ("CLS");
 cout << "Option 2\n";
 memSize();
 break;
 case 3:   system ("CLS");
 cout << "Option 3\n";
 break;
 case 0:   system ("CLS");
 cout << "Exiting!!!\n";
 break;
 default:  system ("CLS");
 cout << "Not a valid selection, please re-choose!\n";
 }
 }while(choice != 0);
 return 0;
 }


 Could someone please look at my code and tell me what I am doing wrong.

 Also, could someone tell me how to return values from the assembly funtion
back
 to the C++ calling program.

 Thanks

 BTW: The assembly funtion finds the total system memory(conventional,
reserved,
 and extended).
Jun 15 2004