4

我正在参加一个操作系统设计课程,其中他们为我们提供了一个用 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

现在,我有点不知所措,因为我对汇编程序并没有真正的经验。我尝试用movl,mov和替换movq,但似乎没有任何效果。这让我相信也许temp是错误的尺寸?

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

void* temp;   // temp pointer used in dispatcher

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

无论如何,显然我不希望有人为我解决这个问题,但是任何可能为我指明正确方向的提示将不胜感激!

4

2 回答 2

2

您显示的行不会将值从%espinto复制到temp- 它相反(正如SET_STACK暗示的那样)。AT&T 语法是src, dest.

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

于 2010-06-24T04:10:39.053 回答
1

您需要使用 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 寻址 temp。

于 2010-06-24T05:09:34.297 回答