64 位问题:尝试使用内联汇编将值从 %rsp 复制到临时变量中

发布于 2024-09-07 04:23:29 字数 1214 浏览 7 评论 0原文

我正在参加一个操作系统设计课程,他们为我们提供了一个用 C 语言编写的微内核,我们正在其上进行构建。内核似乎是为 32 位机器设计的,而我正在运行雪豹。所以我和班上的一个朋友一直在尝试将其破解为 64 位寻址。

最大的问题似乎是一行代码,其中内联汇编用于将当前堆栈指针复制到调度程序使用的临时变量中:

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

自然,编译器会向我吐出错误,因为 %esp是一个32位寄存器。

/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

所以我用 %rsp 替换它,因为它是 64 位堆栈指针寄存器(我认为 %sp 也可以工作,我在这里的其他地方读到 GAS 是足够聪明,可以输入正确的前缀)。将 %esp 替换为 %rsp 后,我收到此错误:

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

现在,我有点不知所措,因为我对汇编程序没有真正的经验。我尝试用 movmovq 替换 movl,但似乎没有任何效果。这让我相信 temp 的大小可能是错误的?

Temp 是一个全局变量,声明如下:

void* temp;   // temp pointer used in dispatcher

我编写了一个快速程序来打印不同数据类型的大小,看起来 x86-64 中的 void* 大小为 8 个字节,这应该是正确的大小,对吧?

不管怎样,显然我不期望任何人为我解决这个问题,但是任何可能为我指明正确方向的提示将不胜感激!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不必你懂 2024-09-14 04:23:29

您显示的行不会将值从 %esp 复制到 temp - 它执行相反的操作(如 SET_STACK 所暗示的那样)。 AT&T 语法为src, dest

一个简单的 asm("mov temp, %rsp"); 应该可以编译。

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.

来世叙缘 2024-09-14 04:23:29

您需要使用 movq 进行 64 位移动。

这是从我的一个项目(火车模拟器的一部分)中执行一些 SSE 工作的程序集片段,注释行是 32 位 intel asm,未注释的是 64 位 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"

        ... );

评论后,我进一步查看,发现所有 64 位 OSX 代码都必须是位置无关的。

还没有 Mac 来测试,但

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

应该可以用。如果没有,您需要为汇编器使用适当的 PIC 寻址。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文