gpt4 book ai didi

c - 与 gcc 相比,为什么 clang 对寄存器变量的行为很奇怪?

转载 作者:太空狗 更新时间:2023-10-29 14:56:54 31 4
gpt4 key购买 nike

背景:

我需要在c代码中获取寄存器值,所以我在gcc usage中找到了这个.我使用以下代码获取 ebp 值。

   register int ebp asm("ebp");
printf("currently ebp is %08x\n", ebp);
// then some code use the value

在我将程序的编译器更改为 clang 之前,一切似乎都还不错。在 gcc 中,它通常会打印类似于 0x7f1284978 的内容,绝对是一个类似于值的指针。

但是当使用 clang 时,输出变得奇怪,它打印出一个像 0x9 这样的值。 ebp 一定不能有这样的值。

问题:

  • clang 不支持这种寄存器变量的使用吗?
  • 为什么不支持这个特性(用下面的代码编译)却没有报警告或错误?

    #include <stdio.h>

    static size_t vfp = 0x233;

    int main(void) {
    register int ebp asm("ebp");
    vfp = (size_t) ebp;
    printf("vfp value is 0x%lx\n", vfp);
    return 0;
    }

最佳答案

长话短说:

Clang 目前不支持显式寄存器变量。

详细信息:

参见 clang documentation

clang only supports global register variables when the register specified is non-allocatable (e.g. the stack pointer). Support for general global register variables is unlikely to be implemented soon because it requires additional LLVM backend support.

在我的机器上(x86_64 ubuntu 16.04),如果我用 Clang-5.0 编译,我得到的程序集是:

 08048410 <main>:
8048410: 55 push %ebp
8048411: 89 e5 mov %esp,%ebp
8048413: 83 ec 18 sub $0x18,%esp
8048416: 8d 05 c0 84 04 08 lea 0x80484c0,%eax
804841c: 8b 4d fc mov -0x4(%ebp),%ecx ;this line is wrong, the behavior is meaningless
804841f: 89 0d 1c a0 04 08 mov %ecx,0x804a01c
8048425: 8b 0d 1c a0 04 08 mov 0x804a01c,%ecx
804842b: 89 04 24 mov %eax,(%esp)
804842e: 89 4c 24 04 mov %ecx,0x4(%esp)
8048432: e8 89 fe ff ff call 80482c0 <printf@plt>
8048437: 89 45 f8 mov %eax,-0x8(%ebp)
804843a: 83 c4 18 add $0x18,%esp
804843d: 5d pop %ebp
804843e: c3 ret
804843f: 90 nop

如果我用 GCC-5.5.0 编译,这是我得到的程序集:

0000051d <main>:


51d: 8d 4c 24 04 lea 0x4(%esp),%ecx
521: 83 e4 f0 and $0xfffffff0,%esp
524: ff 71 fc pushl -0x4(%ecx)
527: 55 push %ebp
528: 89 e5 mov %esp,%ebp
52a: 53 push %ebx
52b: 51 push %ecx
52c: e8 33 00 00 00 call 564 <__x86.get_pc_thunk.ax>
531: 05 a7 1a 00 00 add $0x1aa7,%eax
536: 89 ea mov %ebp,%edx ; this is the correct location to get the value of ebp
538: 89 90 30 00 00 00 mov %edx,0x30(%eax)
53e: 8b 90 30 00 00 00 mov 0x30(%eax),%edx
544: 83 ec 08 sub $0x8,%esp
547: 52 push %edx
548: 8d 90 18 e6 ff ff lea -0x19e8(%eax),%edx
54e: 52 push %edx
54f: 89 c3 mov %eax,%ebx
551: e8 5a fe ff ff call 3b0 <printf@plt>
556: 83 c4 10 add $0x10,%esp
559: 90 nop
55a: 8d 65 f8 lea -0x8(%ebp),%esp
55d: 59 pop %ecx
55e: 5b pop %ebx
55f: 5d pop %ebp
560: 8d 61 fc lea -0x4(%ecx),%esp
563: c3 ret

我们可以看到,GCC 一般支持显式寄存器值访问,而 Clang 不支持。

解决方案:

如果你想使用 Clang 来访问 ebp 值,你可以使用内联汇编,像这样:asm("\t movl %%ebp,%0": "=r"(vfp));

关于c - 与 gcc 相比,为什么 clang 对寄存器变量的行为很奇怪?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55648274/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com