ASM and C++

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
Frode Lillerud

ASM and C++

Post by Frode Lillerud »

Hi, I have a problem with implementing asm into my C++ kernel.

This is my kernel.asm file..

Code: Select all

....
[global geteax]

geteax:
             ret
....
and my kernel.cpp looks like this..

Code: Select all

....
extern long geteax();

int main()
{
...
        long eax = geteax();
...
}
Both:
nasm -f aout ./sources/kernel.asm -o ./objects/asm.o

and
g++ -ffreestanding -fasm -O2 -c ./sources/kernel.cpp -o ./objects/kernel.o

works, but
ld -T ./linking/kernel.lnk -o kernel.bin ./objects/asm.o ./objects/kernel.o

produces an error message:

./objects/kernel.o: In function `main':
./objects/kernel.o(.text+0x42b): undefined reference to `geteax(void)'
make: *** [link] Error 1

Does anyone know what's wrong? ???
whyme_t

Re:ASM and C++

Post by whyme_t »

Maybe the function is getting C++ mangled symbol instead of C symbol.

Try defining geteax in your Kernel as

Code: Select all

extern "C" long geteax(void) ;
Edit - and try adding a leading underscore in your asm

Code: Select all

[global _geteax]
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:ASM and C++

Post by Pype.Clicker »

i'm still wondering why people want such gete*x() functions ... You don't even know what your compiler is going to do with registers, nor if he won't do some tidy-up code between a function that would define some registers' value and your gete*x() function ...
Frode Lillerud

Re:ASM and C++

Post by Frode Lillerud »

Ahh, here we go :)

Rewriting my kernel.cpp to:

Code: Select all

extern "C" long geteax(void);
worked! Thanks whyme_t!

And to respond to Pype.Clicker:

yes, I too realize that an geteax function might not be very useful, but I just needed a simple ASM-codebit to test with. What could be simpler that a 'ret' function? :)

What I'm actually aiming for is to get OS Journal's CPU & Processor Identification to work. It didn't work 'straight out of the box', so i'm trying to write it with a different approach.

Now to rewrite:

Code: Select all

void main() { 
  char VendorSign[13];  
  unsigned long MaxEAX;   

  asm { 
    XOR       EAX,                        EAX 
    CPUID 
    MOV       dword ptr [VendorSign],     EBX 
    MOV       dword ptr [VendorSign+4],   EDX 
    MOV       dword ptr [VendorSign+8],   ECX 
    MOV       dword ptr MaxEAX,           EAX 
} 
  VendorSign[12]=0;  

  printf("Vendor string: %s\n", VendorSign); 
  printf("Maximum EAX value: %i\n", MaxEAX); 

} 
into pure asm.... Hmm... any helpful hints? My problem is where C++-variables are used within the asm-code...
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:ASM and C++

Post by Pype.Clicker »

this is because it's some Vc++ code, no GNU assembler. Gnu asm for it would look like

Code: Select all

{
char vendorid[16];
int maxeax,

asm volatile("xorl %eax,%eax;cpuid":"=b"(vendor),"=d"(vendor+4),"=c"(vendor+8),"=a"(maxeax));
}
Frode Lillerud

Re:ASM and C++

Post by Frode Lillerud »

Hmm, ok so it's VC++.

Is there a good description of the syntax of the

Code: Select all

asm volatile("xorl %eax,%eax;cpuid":"=b"(vendor),"=d"(vendor+4),"=c"(vendor+8),"=a"(maxeax));
somewhere?

I'm having a little difficulty understanding what "=b", and such means...

Also; is it a typo that you've written xorl? It's supposed to be xor, right?
whyme_t

Re:ASM and C++

Post by whyme_t »

I have some asm/C++ code somewhere for executing the cpuid function and accessing private data members of a C++ class. However, this is compiler dependent, and AFAIK my code only works for the latest version of DJGPP.
Frode Lillerud

Re:ASM and C++

Post by Frode Lillerud »

If I could I'd like to take a look at that code, whyme_t. I use GCC, so hopefully it doesn't need too much tweaking.
whyme_t

Re:ASM and C++

Post by whyme_t »

Of course. I'll upload it tonight, when I get back from work. :)

Essentially the way it works is this.
literally - this. The this pointer is implicitly passed to your member function.

Code: Select all

SomeClass::someMethod(this, theFirstParamUMade, etc)
The this pointer points to the first private data member.
whyme_t

Re:ASM and C++

Post by whyme_t »

Code: Select all

void Test::func(int i){
  dValue = i ; //the first declared data member, an int.
}


assembles to ...

Code: Select all

__ZN4Test4funcEi:
    push ebp
    mov ebp, esp
    mov edx, [ebp+0x8] ;base of data members
    mov eax, [ebp+0xc] ; parameter i
    mov [edx+0x0], eax ; move i into dValue
    pop ebp
ret
User avatar
Pype.Clicker
Member
Member
Posts: 5964
Joined: Wed Oct 18, 2006 2:31 am
Location: In a galaxy, far, far away
Contact:

Re:ASM and C++

Post by Pype.Clicker »

Frode Lillerud wrote: Hmm, ok so it's VC++.

Is there a good description of the syntax of the

Code: Select all

asm volatile("xorl %eax,%eax;cpuid":"=b"(vendor),"=d"(vendor+4),"=c"(vendor+8),"=a"(maxeax));
somewhere?

I'm having a little difficulty understanding what "=b", and such means...
this is registers specifications (=b means get the value of ebx and put it in memory at vendor.)
You can find more infos about it with "info gcc", in C extension -> extended ASM.
Also; is it a typo that you've written xorl? It's supposed to be xor, right?
not a typo. This is AT&T syntax. Each mnemonic is followed by the operand size, so "xor al,al" would be written "xorb al,al", "mov dword [x],0" would become "movl $0,x", etc.

I understand it seems weird but that's how GCC will accept asm unless you use the hidden .intel_syntax noprefix directive ...
Frode Lillerud

Re:ASM and C++

Post by Frode Lillerud »

I found a good description of the inline asm syntax.

It's called Inline assembly for x86 in Linux and is written by a guy over at IBM in India.
Post Reply