Page 1 of 1

ASM and C++

Posted: Thu Jan 16, 2003 5:06 am
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? ???

Re:ASM and C++

Posted: Thu Jan 16, 2003 5:17 am
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]

Re:ASM and C++

Posted: Thu Jan 16, 2003 5:33 am
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 ...

Re:ASM and C++

Posted: Thu Jan 16, 2003 6:07 am
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...

Re:ASM and C++

Posted: Thu Jan 16, 2003 6:54 am
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));
}

Re:ASM and C++

Posted: Thu Jan 16, 2003 7:15 am
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?

Re:ASM and C++

Posted: Thu Jan 16, 2003 7:52 am
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.

Re:ASM and C++

Posted: Thu Jan 16, 2003 7:59 am
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.

Re:ASM and C++

Posted: Thu Jan 16, 2003 8:04 am
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.

Re:ASM and C++

Posted: Thu Jan 16, 2003 8:08 am
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

Re:ASM and C++

Posted: Thu Jan 16, 2003 8:16 am
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 ...

Re:ASM and C++

Posted: Fri Jan 17, 2003 2:57 am
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.