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 ker开发者_运维知识库nel 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 temp
is 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!
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.
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.
精彩评论