内联 asm 在 XCode 中为模拟器编译,但无法为设备编译

发布于 2024-10-07 05:23:29 字数 812 浏览 3 评论 0原文

我已经谷歌搜索了很长时间但仍然没有找到解决方案。我希望有人能在这方面帮助我。

我有三个内联 asm 函数,如下所示:

static __inline__ int Bsf(uint32_t Operand) {
  int eax;
  asm __volatile__ (
    "bsfl %0, %0" "\n\t"
    : "=a" (eax)
    : "0" (Operand)
  );
  return eax;
}

static __inline__ int Bsr(uint32_t Operand) {
  int eax;
  asm __volatile__ (
    "bsrl %0, %0" "\n\t"
    : "=a" (eax)
    : "0" (Operand)
  );
  return eax;
}

static __inline__ uint64_t TimeStampCounter(void) {
  uint32_t eax, edx;
  asm __volatile__ (
    "rdtsc" "\n\t"
    : "=a" (eax), "=d" (edx)
    :
  );
  return MAKE_LONG_LONG(eax, edx);
}

它们都在 XCode for Simulator 中成功编译,但当我切换到为 Device - 4.1(适用于 iPhone)构建时失败。我得到的消息是“asm 中不可能的约束”。我相信问题是上面的汇编代码不适用于基于 ARM 的 cpu。有人可以阐明如何重写代码以便为 iPhone cpu 进行编译吗?它可以是汇编代码,也可以是纯 C 代码。提前致谢!

狮子座

I have been googling for quite a long time but still find no solution. I hope someone can help me on this.

I have three inline asm functions as below:

static __inline__ int Bsf(uint32_t Operand) {
  int eax;
  asm __volatile__ (
    "bsfl %0, %0" "\n\t"
    : "=a" (eax)
    : "0" (Operand)
  );
  return eax;
}

static __inline__ int Bsr(uint32_t Operand) {
  int eax;
  asm __volatile__ (
    "bsrl %0, %0" "\n\t"
    : "=a" (eax)
    : "0" (Operand)
  );
  return eax;
}

static __inline__ uint64_t TimeStampCounter(void) {
  uint32_t eax, edx;
  asm __volatile__ (
    "rdtsc" "\n\t"
    : "=a" (eax), "=d" (edx)
    :
  );
  return MAKE_LONG_LONG(eax, edx);
}

They all compiled successfully in XCode for Simulator, but failed when I switched to build for Device - 4.1 (for iPhone ). The message i got is "impossible constraint in asm". I believe the problem is the above assembly code does not work for ARM based cpu. Can someone shed some light on how to re-write the code so it compile for iPhone cpu? It can be either assembly or pure C code. Thanks in advance!

Leo

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

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

发布评论

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

评论(1

不必在意 2024-10-14 05:23:29

您可以尝试使用 ARM clz 指令来替换 bsr。我不知道其他两个有什么好的替代品。

编辑:OP澄清了一些背景。

您需要获取英特尔® 64 和 IA-32 架构软件开发人员手册。它们包含完整的指令集参考,可以帮助您。甚至还有 bsf/bsr 指令的伪代码,并且可以轻松翻译成它们的 C 等效代码:

int Bsf(uint32_t n) {
{
    int m;

    for (m = 0; m < 32; m++)
    {
        if (n & (1 << m))
            return m;
    }

    return 32;
}

int Bsr(uint32_t n) {
{
    int m;

    for (m = 31; m >= 0; m--)
    {
        if (n & (1 << m))
            return m;
    }

    return 32;
}

rdtsc 指令读取处理器的时间-stamp 计数器,它是每个时钟周期递增的 64 位值:

处理器在每个时钟周期单调递增时间戳计数器 MSR,并在处理器重置时将其重置为 0。

您需要弄清楚为什么您的程序需要该信息,以及如何最好地将其转换为您的 ARM 案例。

You could try the ARM clz instruction to replace bsr. I don't know any good replacements for the other two.

Edit: OP clarified some context.

You need to get the Intel® 64 and IA-32 Architectures Software Developer's Manuals. They contain a full instruction set reference which will help you out. Even pseudocode for the bsf/bsr instructions is in there, and can be easily translated into their C equivalents:

int Bsf(uint32_t n) {
{
    int m;

    for (m = 0; m < 32; m++)
    {
        if (n & (1 << m))
            return m;
    }

    return 32;
}

int Bsr(uint32_t n) {
{
    int m;

    for (m = 31; m >= 0; m--)
    {
        if (n & (1 << m))
            return m;
    }

    return 32;
}

The rdtsc instruction reads the processor's time-stamp counter, which is a 64-bit value incremented every clock cycle:

The processor monotonically increments the time-stamp counter MSR every clock cycle and resets it to 0 whenever the processor is reset.

You'll need to figure out why your program needs that information, and how best to translate it to your ARM case.

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