我的第一个汇编程序出错(GCC 内联汇编)

发布于 2024-09-06 18:46:43 字数 659 浏览 4 评论 0原文

经过大量的互联网研究后,我在 C++ 程序中实现了一个小型汇编程序例程,以使用 cpuid 获取 CPU 的 L1 缓存大小。

int CPUID_getL1CacheSize() {

    int l1CacheSize = -1;

    asm ( "mov $5, %%eax\n\t"   // EAX=80000005h: L1 Cache and TLB Identifiers
          "cpuid\n\t"
          "mov %%eax, %0"       // eax into l1CacheSize 
          : "=r"(l1CacheSize)   // output 
          :                     // no input
          : "%eax"              // clobbered register
         );

    return l1CacheSize;
}

它可以在带有 MinGW(GCC、G++)的 Windows 7 64 位上完美运行。接下来,我使用 GCC 4.0 在 Mac 计算机上尝试了此操作,并且某处一定有错误,因为我的程序在组合框中显示奇怪的字符串,并且某些信号无法连接(Qt GUI)。

这是我的第一个汇编程序,希望有人能给我提示,谢谢!

After a lot of internet research I implemented a small assembler routine in my C++ program to get the CPU's L1 cache size using cpuid.

int CPUID_getL1CacheSize() {

    int l1CacheSize = -1;

    asm ( "mov $5, %%eax\n\t"   // EAX=80000005h: L1 Cache and TLB Identifiers
          "cpuid\n\t"
          "mov %%eax, %0"       // eax into l1CacheSize 
          : "=r"(l1CacheSize)   // output 
          :                     // no input
          : "%eax"              // clobbered register
         );

    return l1CacheSize;
}

It works perfectly on Windows 7 64 bit with MinGW (GCC, G++). Next I tried this on my Mac computer using GCC 4.0 and there must be an error somewhere because my program shows strange strings in the ComboBoxes and some signals cannot be connected (Qt GUI).

This is my first assembler program, I hope someone can give me a hint, Thanks!

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

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

发布评论

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

评论(2

别靠近我心 2024-09-13 18:46:43

我认为 CPUID 实际上破坏了 EAX、EBX、ECX、EDX,所以这可能只是一个寄存器垃圾问题。以下代码似乎可以在 Mac OS X 上的 gcc 4.0.1 和 4.2.1 中正常工作:

#include <stdio.h>

int CPUID_getL1CacheSize()
{
    int l1CacheSize = -1;

    asm ( "mov $5, %%eax\n\t"   // EAX=80000005h: L1 Cache and TLB Identifiers
          "cpuid\n\t"
          "mov %%eax, %0"       // eax into l1CacheSize 
          : "=r"(l1CacheSize)   // output 
          :                     // no input
          : "%eax", "%ebx", "%ecx", "%edx"  // clobbered registers
         );

    return l1CacheSize;
}

int main(void)
{
    printf("CPUID_getL1CacheSize = %d\n", CPUID_getL1CacheSize());
    return 0;
}

请注意,您需要使用 -fno-pic 进行编译,因为启用 PIC 时会保留 EBX。 (要么您需要采取措施保存和恢复 EBX)。

$ gcc-4.0 -Wall -fno-pic cpuid2.c -o cpuid2
$ ./cpuid2 
CPUID_getL1CacheSize = 64
$ gcc-4.2 -Wall -fno-pic cpuid2.c -o cpuid2
$ ./cpuid2 
CPUID_getL1CacheSize = 64
$ 

I think that CPUID actually clobbers EAX, EBX, ECX, EDX, so it's probably just a register trashing problem. The following code appears to work OK with gcc 4.0.1 and 4.2.1 on Mac OS X:

#include <stdio.h>

int CPUID_getL1CacheSize()
{
    int l1CacheSize = -1;

    asm ( "mov $5, %%eax\n\t"   // EAX=80000005h: L1 Cache and TLB Identifiers
          "cpuid\n\t"
          "mov %%eax, %0"       // eax into l1CacheSize 
          : "=r"(l1CacheSize)   // output 
          :                     // no input
          : "%eax", "%ebx", "%ecx", "%edx"  // clobbered registers
         );

    return l1CacheSize;
}

int main(void)
{
    printf("CPUID_getL1CacheSize = %d\n", CPUID_getL1CacheSize());
    return 0;
}

Note that you need to compile with -fno-pic as EBX is reserved when PIC is enabled. (Either that or you need to take steps to save and restore EBX).

$ gcc-4.0 -Wall -fno-pic cpuid2.c -o cpuid2
$ ./cpuid2 
CPUID_getL1CacheSize = 64
$ gcc-4.2 -Wall -fno-pic cpuid2.c -o cpuid2
$ ./cpuid2 
CPUID_getL1CacheSize = 64
$ 
巴黎盛开的樱花 2024-09-13 18:46:43

我终于解决了这个问题。我在玩游戏时遇到编译器错误:“错误:PIC 寄存器 '%ebx' 在 'asm' 中被破坏”,经过一些互联网研究后,我将代码修改为:

int CPUID_getL1CacheSize() {

int l1CacheSize = -1;

asm volatile ( "mov $5, %%eax\n\t"
               "pushl %%ebx; cpuid; popl %%ebx\n\t"
               "mov %%eax, %0"
               : "=r"(l1CacheSize)
               :
               : "%eax"
               );

return l1CacheSize;

}

谢谢 Paul,编译器选项 -fno- pic 也是一个不错的解决方案。
问候

I finally resolved the problem. I got a compiler error while playing around: "error: PIC register '%ebx' clobbered in 'asm'" and after some internet research I modified my code to:

int CPUID_getL1CacheSize() {

int l1CacheSize = -1;

asm volatile ( "mov $5, %%eax\n\t"
               "pushl %%ebx; cpuid; popl %%ebx\n\t"
               "mov %%eax, %0"
               : "=r"(l1CacheSize)
               :
               : "%eax"
               );

return l1CacheSize;

}

Thanks Paul, The compiler option -fno-pic is a nice solution too.
Greetings

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