C/C 索引跳入一组NOP



我想以一个时钟的分辨率产生延迟,因此我的想法是要使255个接头一个接一个地,然后跳到最后一个减去所需的延迟。因此,0将跳过最后一个NOP,1到最后一个NOP,而255到第一个NOP。

我以前使用过索引函数调用,但在类似的索引gotos上找不到任何东西。我还考虑过使用开关语句,但似乎有其他说明。

感激地收到的任何建议。

尼克·奥德尔(Nick Odell)有一个不错的解决方案,但是编译器无法知道您的所有情况都完全具有一个代码字节。直到汇编器通行证才能知道这一点。因此,无论您在每种情况下生产多少代码,编译器都必须产生可以工作的东西,而间接跳台确实是这样做的唯一方法。

因此,我认为为了获得"理想"代码,每个nop一个字节,您也必须在汇编中编写跳跃逻辑。

这是我想到的(对于Linux上的GCC/AMD64/GAS)。在这里,它在Godbolt上。

#include <stdlib.h>
#define N 1000
#define xstr(s) str(s)
#define str(s) #s

void delay(unsigned ticks) {
  if (ticks <= N) {
    asm("movq $1f, %%rax n"
    "addq %0, %%rax n"
    "jmp *%%rax n"
    "1: n"
    ".rept " xstr(N) " n"
    "nop n"
    ".endr n"
    : : "g" ((unsigned long)(N-ticks)): "ax");
  } else {
    abort();
  }
}
int main(void) {
  delay(4);
  return 0;
}

请注意,必须用-no-pie编译。如果您希望它作为独立于位置的可执行文件工作,则可能需要call 2f ; 2f: popq %rax之类的技巧将绝对程序地址输入寄存器。

当然,总是有一个问题,即实际进入此代码的开销是否会弄乱您的延迟时间的准确性...

相关内容

  • 没有找到相关文章

最新更新