Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

Passing Values Between C++ Builder 6 and Assembly

Posted on 2006-10-23
3
Medium Priority
?
636 Views
Last Modified: 2013-11-17
The C++ program wants to get access to a value contained in an assembly program (file3.txt).  When the C++ program is compiled, it reports "[C++ Error] ThirdAssembly.cpp(16): E2215 Linkage specification not allowed".  What needs to be changed?

The C++ program:
 #include <vcl.h>
 #pragma hdrstop
 #include <iostream>
 #include <stdio.h>

 //---------------------------------------------------------------------------

 #pragma argsused
 int main(int argc, char* argv[])

 {
        using namespace std;
        int a; //defines a numeric integer
        int b;
        int * ted; //defines a dereferenced pointer
        extern "C" int mydata;
        char s[100]; //defines string variable containing up to 100 chars

        asm
        {
         #include <file3.txt>    //defines a table with ten integers
        }

        cout << "mydata: "<<mydata<<endl;

        cout << "Type an integer: ";
        cin >> a;
        cout <<"You typed: "<<a<<endl<<endl<<endl;
        ted = &a;
        cout <<"Address of the integer: "<<ted<<endl;


        cout <<"Assembly will change the integer to 23 ---"<<endl;
        asm mov a,23
        cout <<"Integer in C++ has been changed to: "<<a<<endl<<endl;

        b = *ted;
        cout <<"Value of *ted from dereferencing the memory address pointer: "<<b<<endl<<endl;

        cout <<"Assembly will change the integer to 46 ---"<<endl;
        asm
        {
         #include <file2.txt>
        }
        cout <<"Integer in C++ has been changed to: "<<a<<endl<<endl;
        b = *ted;
        cout <<"Value of *ted from dereferencing the memory address pointer: "<<b<<endl<<endl;
       
        cin >> s;

        return 0;
 }
 //---------------------------------------------------------------------------


The assembly program (file3.txt):
_mydata: db 101


0
Comment
Question by:apx_31088
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
3 Comments
 
LVL 18

Expert Comment

by:Jose Parrot
ID: 17798716
Hi,

The types must be coherent between C++ and ASM codes.
For exemple:

    WORD variable = 10; // must be same size as register we will use
    asm
    {
        mov ax,variable
        shr ax,1          
        mov variable,ax
    }
    Edit1->Text = variable;

I have noticed also that
        extern "C" int mydata;
was declared inside main. As far I remember, it should be global. Outside main.

Right now I don't have access to my Builder C++. Later I will be back, if some colleague didn't post the right answer to you.

Jose
0
 
LVL 18

Accepted Solution

by:
Jose Parrot earned 2000 total points
ID: 17800925
Yes, confirming:
   extern "C" int mydata;
should be global, thus outside main. For example, immediately after
  extern "C" int mydata;
This solves the   Linkage specification not allowed   error. But unfortunately new problems appear.

The code
        asm
        {
         #include <file2.txt>
        }
will translate to
        asm
        {
         mydata: db 101
        }
So mydata will be local to the braces, never accessible outside them.

If we invoke file2.txt without braces, as below:
        asm
         #include <file2.txt>
it translates to
        asm mydata: db 101
and this is an error. How about a variable mixed with instructions to the CPU? We can't insert a variable between statements of assembler code.

To reserve memory space for variables we must separate them from the execution code. For example:
asm
{
   jmp begin
   variable_a: db 'This is a phrase.', 0ah, 0dh
   variable_b: dw 101
begin:
   nop
}

The problem is that, anyway, such variables are local to the assembly function.
Then, you should declare all the variables you need access from C++ inside the C++ code.
Let inside the assembly code just the variables that are local to those functions.
Of course we can create extern data area, but it is out of scope of asm statement.
Take in count that for short assembly code we can use asm, for long assembly code, we should compile an assembly code, create its obj file and link it. If we want an  extern variable  we must construct it extern. With  asm  it is "internal".


As an example of how to manage that, take a look at your code with some modifications:

MAIN PROGRAM
#include <vcl.h>
#pragma hdrstop
#include <iostream>
#include <stdio.h>
//extern "C" int mydata; <---- use it inside the C/C++ code. Sorry...
#pragma argsused
int main(int argc, char* argv[])

{
        using namespace std;
        int a; //defines a numeric integer
        int b;
        int mydata=0x101;
        int * ted; //defines a dereferenced pointer
        char s[100]; //defines string variable containing up to 100 chars

        asm
        {
         #include "file3.txt"    
        }

        cout << "mydata: "<<mydata<<endl;

        cout << "Type an integer: ";
        cin >> a;
        cout <<"You typed: "<<a<<endl<<endl<<endl;
        ted = &a;
        cout <<"Address of the integer: "<<ted<<endl;


        cout <<"Assembly will change the integer to 23 ---"<<endl;
        asm mov a,23
        cout <<"Integer in C++ has been changed to: "<<a<<endl<<endl;

        b = *ted;
        cout <<"Value of *ted from dereferencing the memory address pointer: "<<b<<endl<<endl;

        cout <<"Assembly will change the integer to 46 ---"<<endl;
        asm
        {
         #include "file2.txt"
        }
        cout <<"Integer in C++ has been changed to: "<<a<<endl<<endl;
        b = *ted;
        cout <<"Value of *ted from dereferencing the memory address pointer: "<<b<<endl<<endl;

        cin >> s;

        return 0;
}
//---------------------------------------------------------------------------

FILE2.TXT
shl a,1
//---------------------------------------------------------------------------

FILE3.TXT
jmp start
mydata: db  12   <--- this is local to this code
variable_a: db 'This is a phrase.', 0ah, 0dh
start: nop
//---------------------------------------------------------------------------

Please note, in FILE3.TXT we separate data and code by jumping over the data area. For a more sophisticated assembly code, you should use DATA segments for data storage.

Jose
0
 

Author Comment

by:apx_31088
ID: 17803040
Hola! Jose ---

     Thank you for writing those examples!
     I have two questions:
      1. How to access the value of the byte at address mydata in File3.Txt from the calling C++ program?
      2. How to access the address of mydata and variable_a in File3.Txt from the calling C++ program?

Mucho Gracias,
    Chuck
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

In our object-oriented world the class is a minimal unit, a brick for constructing our applications. It is an abstraction and we know well how to use it. In well-designed software we are not usually interested in knowing how objects look in memory. …
How to install Selenium IDE and loops for quick automated testing. Get Selenium IDE from http://seleniumhq.org Go to that link and select download selenium in the right hand column That will then direct you to their download page. From that p…
THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.
The viewer will learn how to use and create new code templates in NetBeans IDE 8.0 for Windows.
Suggested Courses

688 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question