views:

48

answers:

2

I'm taking an operating systems design class in which they have given us a microkernel written in C that we're building on top of. The kernel seems to have been designed with 32-bit machines in mind and I'm running snow leopard. So a friend in the class and I have been trying to hack it into 64-bit addressing.

The biggest issue seems to be one line of code, where inline assembly is utilized to copy the current stack pointer into a temporary variable used by the dispatcher:

#define SET_STACK(s) asm("movl temp,%esp");

Naturally, the compiler spits back errors at me because %esp is a 32-bit register.

/var/folders/0A/0AVWZC-5HhOg6twWZBlDgU+++TI/-Tmp-//cckS2oq7.s:523:32-bit absolute addressing is not supported for x86-64
/var/folders/0A/0AVWZC-5HhOg6twWZBlDgU+++TI/-Tmp-//cckS2oq7.s:523:cannot do signed 4 byte relocation

So I replaced it with %rsp because it's the 64-bit stack pointer register (and I think just %sp works as well, I read somewhere else on here that GAS is smart enough to put the right prefix). After replacing %esp with %rsp, I get this error:

/var/folders/0A/0AVWZC-5HhOg6twWZBlDgU+++TI/-Tmp-//cc8TLdjH.s:523:Incorrect register `%sp' used with `l' suffix

Now, I'm a bit at a loss because I'm not really experienced with assembler. I've tried replacing movl with mov, and movq, but nothing seems to work. Which leads me to believe that maybe tempis the wrong size?

Temp is a global variable, declared like so:

void* temp;   // temp pointer used in dispatcher

I wrote a quick program to print out the sizes of different datatypes, and it seems like void* in x86-64 are 8 bytes in size, which should be the right size, right?

Anyway, obviously I don't expect anyone to solve this problem for me, but any tips that might point me in the right direction would be much appreciated!

UPDATE If anyone is willing to take a quick look at the code I have it posted on github. http://github.com/jarsen/os345

The macro in question is on line 166 of http://github.com/jarsen/os345/blob/master/os345.h

The variable tempis defined on line 65, assigned a value on 350, and the macro is called on 351 of http://github.com/jarsen/os345/blob/master/os345.c

It looks like temp is being cast as an int*, which I suspect is causing the issues... although as a pointer it should be 8 bytes, so should be the right size... right?

+1  A: 

The line you've shown doesn't copy the value from %esp into temp - it does the opposite (as the SET_STACK implies). AT&T syntax is src, dest.

A simple asm("mov temp, %rsp"); should compile.

caf
Huh, good to know that I had it backwards. Thanks.I've actually tried mov, and just tried it again, but it still give me this:/var/folders/0A/0AVWZC-5HhOg6twWZBlDgU+++TI/-Tmp-//ccBKG90T.s:523:32-bit absolute addressing is not supported for x86-64/var/folders/0A/0AVWZC-5HhOg6twWZBlDgU+++TI/-Tmp-//ccBKG90T.s:523:cannot do signed 4 byte relocationDoes that mean that it doesn't think temp is the right size to move into %rsp?
Jarsen
@Jarsen: Sounds like it. That works fine for me though.
caf
... signed 4 byte relocation... make me thing about alignment... possible? maybe void*temp should by quad-aligned (quad I mean, 64bit)? ... but `32-bit absolute addressing is not supported for x86-64` makes me think that for some reason it consider "temp" like a 32bit absolute address (why should it be so? it shouldn't...);interesting, alas no 64b machine to do tests
ShinTakezou
+1  A: 

You need to use movq for 64bit moves.

Here is a snippet of assembly doing some SSE work from one of my projects (part of a train simulator), The commented lines are 32bit intel asm, uncommented is 64bit AT&T.

asm(
        //mykda calculation
        //mov eax, dword ptr [train_traction_ptr]
        //movaps xmm0, xmmword ptr [eax] //train_traction[i] + forceFront
        "movq %0, %%rax\n\t"
        "movaps (%%rax), %%xmm0\n\t"

        //mov eax, dword ptr [local_fgrr_ptr]
        //movaps xmm1, xmmword ptr [rax]
        //addps xmm0, xmm1
        "movq %1, %%rax\n\t"
        "movaps (%%rax), %%xmm1\n\t"
        "addps %%xmm1, %%xmm0\n\t"

        ... );

After comment I looked further and found that all 64bit OSX code has to be position independant.

Haven't got a Mac to test, but

asm ("movq temp(%rip),%rsp");

Should work. If not, you need to use the appropriate PIC addressing for temp for your assembler.

Hayman
Thanks for the reponse. I actually have tried movq, but I still get the following error from gcc: /var/folders/0A/0AVWZC-5HhOg6twWZBlDgU+++TI/-Tmp-//cc7VMqAZ.s:523:32-bit absolute addressing is not supported for x86-64/var/folders/0A/0AVWZC-5HhOg6twWZBlDgU+++TI/-Tmp-//cc7VMqAZ.s:523:cannot do signed 4 byte relocationDo you think this means it thinks temp is 4 bytes and can't move it into %rsp?
Jarsen
@Jarsen - see edit
Hayman
I tried it out and it didn't work, but asked me it asked me if I meant _temp, so I assumed I did. And that seemed to fix the problem:asm ("movq _temp(%rip),%rsp");So thanks a lot! Works for now, hopefully I don't run into anything nasty later on.Just for my own benefit, if you still have the URL or whatever where you found this information could you give it to me? Thanks so much.
Jarsen
No worries dude.This was one URL in particular -http://lists.apple.com/archives/xcode-users/2006/Sep/msg00060.htmlIf you google for the "absolute addressing" error there a lot of forum posts. I imagine Apple would have some documentation floating around somewhere, though I didn't see it in my search.
Hayman