How to pass variables from a C++ function into inline ASM

P

Protoman

I'm having the trouble getting the inline assembler and/or linker of
Dev-Cpp to see my variable that's been passed into the C++ fn where the
inline ASM code is. Can anyone help me figure out how to get this to
work? The specific error is "[Linker error] undefined reference to
`val'". And here's my program:

#include <iostream>
#include <cstdlib>
using std::cout;
using std::cin;
using std::endl;
using std::system;

int Double(int val)
{
asm("mov eax,val \n");
asm("add eax,eax \n");
asm("mov val,eax \n");
return val;
}

int main()
{
int val;
cout << "Enter a value: " << endl;
cin >> val;
cout << val << "*2=" << Double(val) << endl;
system("PAUSE");
return EXIT_SUCCESS;
}

If anyone could help, that'd be great. Thanks!!!!
 
T

Tim Roberts

Protoman" said:
I'm having the trouble getting the inline assembler and/or linker of
Dev-Cpp to see my variable that's been passed into the C++ fn where the
inline ASM code is. Can anyone help me figure out how to get this to
work? The specific error is "[Linker error] undefined reference to
`val'". And here's my program:

#include <iostream>
#include <cstdlib>
using std::cout;
using std::cin;
using std::endl;
using std::system;

int Double(int val)
{
asm("mov eax,val \n");
asm("add eax,eax \n");
asm("mov val,eax \n");
return val;
}

The problem here is that the name "val" does not survive into the assembler
that gcc creates. By the time it becomes assembly, it's something like
$ebp+4.

Inline assembler in gcc is a non-trivial, guru-level topic. To summarize,
you need to give gcc a list of "constraints" that tell it where the
variable is. For example, your function might look like this:

int Double(int val)
{
asm( "add %%eax, %%eax"
: "a" (val),
: "a" (val)
: );
}

The first "a" clause tells it that "register eax is an output from this
sequence and should be stored in val". The second "a" clause tells it that
"register eax is an input to this sequence and should be loaded from val."

It is also possible to let the compiler choose the register by using a "r"
constraint, and use "%0" in the instructions, but I don't know if you can
have a single register be both an input and an output with that method.
 
P

Protoman

Tim said:
Protoman" said:
I'm having the trouble getting the inline assembler and/or linker of
Dev-Cpp to see my variable that's been passed into the C++ fn where the
inline ASM code is. Can anyone help me figure out how to get this to
work? The specific error is "[Linker error] undefined reference to
`val'". And here's my program:

#include <iostream>
#include <cstdlib>
using std::cout;
using std::cin;
using std::endl;
using std::system;

int Double(int val)
{
asm("mov eax,val \n");
asm("add eax,eax \n");
asm("mov val,eax \n");
return val;
}

The problem here is that the name "val" does not survive into the assembler
that gcc creates. By the time it becomes assembly, it's something like
$ebp+4.

Inline assembler in gcc is a non-trivial, guru-level topic. To summarize,
you need to give gcc a list of "constraints" that tell it where the
variable is. For example, your function might look like this:

int Double(int val)
{
asm( "add %%eax, %%eax"
: "a" (val),
: "a" (val)
: );
}

The first "a" clause tells it that "register eax is an output from this
sequence and should be stored in val". The second "a" clause tells it that
"register eax is an input to this sequence and should be loaded from val."

It is also possible to let the compiler choose the register by using a "r"
constraint, and use "%0" in the instructions, but I don't know if you can
have a single register be both an input and an output with that method.

Now it's saying: 21 C:\Dev-Cpp\ASM.cpp expected string-literal before
':' token

Code:

#include <iostream>
#include <cstdlib>
using std::cout;
using std::cin;
using std::endl;
using std::system;

int Double(int val);

int main()
{
int val;
cout << "Enter a value: " << endl;
cin >> val;
cout << val << "*2=" << Double(val) << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
int Double(int val)
{
asm("add eax,eax":"a"(val),:"a"(val));
return val;
}
 
J

Jim Carlock

Protoman said:
And here's my program:

#include <iostream>
#include <cstdlib>

Aren't those items supposed to have an .h extension? For
example...

#include <iostream.h>
#include <cstdlib.h>

Hope this helps.
 
P

Protoman

Jim said:
Aren't those items supposed to have an .h extension? For
example...

#include <iostream.h>
#include <cstdlib.h>

Hope this helps.

Hey, Jimmy-boy, ever heard of a little thing called "using namespace
std;"? Have you even heard of namespace std, the C++ Standard
namespace? And I REALLY don't think THAT's the problem here.
 
T

Tim Roberts

Protoman" said:
Now it's saying: 21 C:\Dev-Cpp\ASM.cpp expected string-literal before
':' token

My fault, I put an extra comma in there. Replace the ,: with just :
int Double(int val)
{
asm("add eax,eax":"a"(val),:"a"(val)); ^
return val;
}

Do you have a Linux system handy? Almost everything I learned about gcc
inline assembler, I learned from two places: perusing the include files in
a Linux distribution, and this very handy tutorial:

http://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html
 
P

Protoman

Tim said:
My fault, I put an extra comma in there. Replace the ,: with just :


Do you have a Linux system handy? Almost everything I learned about gcc
inline assembler, I learned from two places: perusing the include files in
a Linux distribution, and this very handy tutorial:

http://www.delorie.com/djgpp/doc/brennan/brennan_att_inline_djgpp.html

OK, I fixed that, now it says: 21 C:\Dev-Cpp\ASM.cpp output operand
constraint lacks `=' Which one is output?
 
P

Phil Carmody

Protoman" said:
OK, I fixed that, now it says: 21 C:\Dev-Cpp\ASM.cpp output operand
constraint lacks `=' Which one is output?

Oh for ****'s sake. That is answered quite near the top of the page
Tim pointed you towards. From this we can only infer bad things
about the intelligence of people who think "Win-XP rules". Thanks
for reinforcing the stereotype.

Phil
 
P

Protoman

Phil said:
Oh for ****'s sake. That is answered quite near the top of the page
Tim pointed you towards. From this we can only infer bad things
about the intelligence of people who think "Win-XP rules". Thanks
for reinforcing the stereotype.

Phil

Actually, about two nanoseconds after I posted "WinXP rules!!!!", I
found and fixed the problem myself, but my router went down, so I
couldn't tell you. Bye.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Staff online

Members online

Forum statistics

Threads
473,995
Messages
2,570,230
Members
46,816
Latest member
SapanaCarpetStudio

Latest Threads

Top