64-bit issues: trying to copy value from% rsp to temp variable using inline assembly

I take the operating system development class in which they gave us a microkernel written in C that we build on top. The kernel seems to have been designed with 32-bit machines in mind, and I'm running a snow leopard. So, a friend in the class, and I tried to crack it into 64-bit addressing.

The biggest problem is one line of code in which the built-in assembly is used to copy the current stack pointer to a temporary variable used by the dispatcher:

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

Naturally, the compiler throws 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 is a 64-bit stack pointer register (and I think that just %sp works, I read somewhere else here that GAS is smart enough to place the correct 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 little confused because I'm not very good at assembler. I tried replacing movl with mov and movq , but nothing works. What makes me think that maybe temp is the wrong size?

Temp is a global variable declared like this:

 void* temp; // temp pointer used in dispatcher 

I wrote a short program for printing the sizes of different types of data, and it seems that void * in x86-64 is 8 bytes in size, which should be the right size, right?

In any case, obviously, I do not expect anyone to solve this problem for me, but any advice that can point me in the right direction will be very grateful!

+4
source share
2 answers

You need to use movq for 64-bit moves.

Here is a build fragment that does some SSE work from one of my projects (part of a train simulator). Commented lines - 32-bit intel asm, uncommented - 64-bit 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 the comment, I looked further and found that all 64-bit OSX codes should be position-independent.

I do not have a Mac to test, but

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

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

+1
source

The selected line does not copy the value from %esp to temp - it does the opposite (as follows from SET_STACK ). Syntax AT & T - src, dest .

Simple asm("mov temp, %rsp"); must compile.

+2
source

Source: https://habr.com/ru/post/1313723/


All Articles