Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
June 14, 2004 Calling assembly functions from C++. | ||||
---|---|---|---|---|
| ||||
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). |
June 14, 2004 Re: Calling assembly functions from C++. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Noob_programmer | 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). > > > > > |
June 15, 2004 Re: Calling assembly functions from C++. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | 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). >> >> >> >> >> > > |
June 15, 2004 Re: Calling assembly functions from C++. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | 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). >> >> >> >> >> > > |
June 15, 2004 Re: Calling assembly functions from C++. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Noob_programmer | "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. |
June 18, 2004 Re: Calling assembly functions from C++. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | 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. > > |
June 19, 2004 Re: Calling assembly functions from C++. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Noob_programmer | 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. > > > > > > |
June 19, 2004 Re: Calling assembly functions from C++. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Noob_programmer | 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 |
June 19, 2004 Re: Calling assembly functions from C++. | ||||
---|---|---|---|---|
| ||||
Posted in reply to Noob_programmer | 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 |
Copyright © 1999-2021 by the D Language Foundation