2015-04-07 33 views
0

我写了一个汇编程序,需要在x86-64上的5个GPR工作正常。但我试图将其移植到32位x86。编译器抱怨不可能使用5个GPR。x86汇编技巧,以获得更多的GPR

代码的x86-64低于:

__asm__("mov %0,%%r8\n\t" 
      "mov %1,%%r10\n\t" 
      "lfence\n\t" 
      "rdtsc\n\t" 
      "mov %%eax,%%edi\n\t" 
      "mov (%%r8), %%r8\n\t" 
      "mov (%%r8), %%r8\n\t" 
      "mov (%%r8), %%r8\n\t" 
      "mov (%%r8), %%r8\n\t" 
      "mov (%%r8), %%r8\n\t" 
      "mov (%%r8), %%r8\n\t" 
      "mov (%%r8), %%r8\n\t" 
      "mov (%%r8), %%r8\n\t" 
      "mov (%%r8), %%r8\n\t" 
      "mov (%%r8), %%r8\n\t" 
      "mov (%%r8), %%r8\n\t" 
      "mov (%%r8), %%r8\n\t" 
      "mov (%%r8), %%r8\n\t" 
      "mov (%%r8), %%r8\n\t" 
      "mov (%%r8), %%r8\n\t" 
      "mov (%%r8), %%r8\n\t" 
      "lfence\n\t" 
      "rdtsc\n\t" 
      "sub %%edi, %%eax\n\t" 
      "mov %%eax, (%%r10)\n\t" 
      : 
      :"r"(head),"r"(time_buf) 
      :"eax","edx","edi","r8","r10" 
     ); 

我怎样才能解决这个问题?

处理器:英特尔®酷睿™2双核处理器T9400

+0

如果你已经用完了寄存器,就没办法。你需要将一些值泄漏到内存中。另一种方法是泄漏到SSE/AVX寄存器,但我认为除非您尝试对代码进行矢量化,否则性能不会更好。您可以使用'-fomit-frame-pointer'在32位模式下获得最多7个GPR。 –

+0

你可以将'%ebx','%ebp'和''end'弹出来,在asm语句本身中。当然,编译器在此情况下不会意识到它们的使用。但给出的答案可能是你真正想要的。就目前而言,你的代码是不正确的 - 你不知道你的clobbered寄存器是别名'%0'还是'%1'。 –

回答

2

你实际上并不需要5个寄存器,你只需要4寄存器EAX和EDX是由RDTSC指令打一顿,所以这两项。您需要另一个寄存器来保存来自第一条RDTSC指令的值EAX。那是三。第四个寄存器是指针的head。您使用的另一个注册表不需要,无需计算或存储asm语句中的已用时间。你可以在普通的C/C++代码中做到这一点。

我已经重写你的汇编语句是这样的:

unsigned 
foo(void *head) { 
    unsigned time_start, time_end; 

    __asm__("lfence\n\t" 
     "rdtsc\n\t" 
     "mov %%eax, %0\n\t" 
     "mov (%1), %1\n\t" 
     "mov (%1), %1\n\t" 
     "mov (%1), %1\n\t" 
     "mov (%1), %1\n\t" 
     "mov (%1), %1\n\t" 
     "mov (%1), %1\n\t" 
     "mov (%1), %1\n\t" 
     "mov (%1), %1\n\t" 
     "mov (%1), %1\n\t" 
     "mov (%1), %1\n\t" 
     "mov (%1), %1\n\t" 
     "mov (%1), %1\n\t" 
     "mov (%1), %1\n\t" 
     "mov (%1), %1\n\t" 
     "mov (%1), %1\n\t" 
     "mov (%1), %1\n\t" 
     "lfence\n\t" 
     "rdtsc" 
     : "=r" (time_start), "+r" (head), "=a" (time_end) 
     : 
     : "edx" 
     ); 
    return time_end - time_start; 
} 

这汇编语句让编译器挑寄存器在可能的情况。 EAX和EDX的使用由RDTSC指令固定,但用于保存time_start时间戳和head指针的寄存器留给编译器选择。

除了使用少一个寄存器之外,我的示例asm语句具有无需修改即可在32位和64位下工作的优点。

+0

谢谢你的见解。 – drdot