Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/55.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
gcc-作为调试标签的结构 背景:_C_Gcc_Assembly - Fatal编程技术网

gcc-作为调试标签的结构 背景:

gcc-作为调试标签的结构 背景:,c,gcc,assembly,C,Gcc,Assembly,Linux 64 我想要一种方法,告诉gcc在使用gcc-O0-S-gmyprog.c 我的意思是:不是通过地址引用结构,而是通过标签引用它们。这将简化解析,而无需再次读取源代码 例如: struct mystruct{ int32_t a; char * b; } 会变成这样: label_mystruct: -4(label_mystruct) -12(label_mystruct) 例如,引用: add $56, -4(label_mystruct)

Linux 64

我想要一种方法,告诉gcc在使用
gcc-O0-S-gmyprog.c

我的意思是:不是通过地址引用结构,而是通过标签引用它们。这将简化解析,而无需再次读取源代码

例如:

struct mystruct{
    int32_t a;
    char * b;
}
会变成这样:

label_mystruct:
    -4(label_mystruct)
    -12(label_mystruct)
例如,引用:

add $56, -4(label_mystruct)
目前,它被引用为

.globl _main
_main:
LFB13:
LM157:
    pushq %rbp  #
LCFI27:
    movq %rsp, %rbp#,
LCFI28:
    subq $80, %rsp#,
    movl %edi,-68(%rbp) # argc, argc,
    movq %rsi,-80(%rbp) # argv, argv

    Next line is the culprit:
    movq -56(%rbp), %rdx # list, D.3781
    movq -16(%rbp), %rax # arr, D.3780
    movq %rdx, %rsi # D.3781,
    movq %rax, %rdi # D.3780,
    call _myaddhu   #
我希望是这样

label_mystruct:
    -4(label_mystruct)
    -12(label_mystruct)

.globl _main
_main:
LFB13:
LM157:
    pushq %rbp  #
LCFI27:
    movq %rsp, %rbp#,
LCFI28:
    subq $80, %rsp#,
    movl %edi,-68(%rbp) # argc, argc,
    movq %rsi,-80(%rbp) # argv, argv

    Now it is fine:
    movq label_mystruct, %rdx # list, D.3781
    movq -16(%rbp), %rax # arr, D.3780
    movq %rdx, %rsi # D.3781,
    movq %rax, %rdi # D.3780,
    call _myaddhu   #
问题:
有了gcc,而不使用外部工具,这是可能的吗?

我认为这是不可能的,这是由gcc中使用的设置决定的

这里的问题是,这里的结构存储在堆栈上,您不能真正拥有引用堆栈上某些内容的标签。如果该结构不在堆栈上,它会有一个引用它的标签(例如,如果它是一个全局变量)

另一方面,GCC将生成调试信息,其中包含有关运行特定代码时放置的数据的信息。在您的示例中,它在本质上说“当执行此代码时-56(%ebp)指向
mystruct

另一方面,如果你想手工编写汇编代码,你当然可以对变量进行符号引用。例如,您可以执行以下操作:

#define MYSTRUCT -56(%ebp)

...
movq MYSTRUCT, %rdx 

但是,
MYSTRUCT
将被扩展,并且在组装代码期间该符号将丢失。如果GCC做到这一点(除了由
-s
生成的汇编程序代码可能更可读之外)将没有任何帮助,此外,GCC不会通过预处理器传递汇编程序(因为它不会这样做)。

如果将结构放入静态存储中,您就会得到它。这当然改变了代码的含义。例如,此代码

struct {
    int a, b;
} test;

int settest(int a, b) {
    test.a = a;
    test.b = b;
}
编译到(已清理):


您还可以尝试将选项
-fverbose asm
传递给gcc,该选项指示gcc添加一些注释,使程序集更易于阅读。

什么是“保持结构原样”的意思?顺序保证相同(位字段AFAIK除外)。你指的是填充吗?我的问题是我丢失了结构定义方式的信息。在解析时,我希望能够知道我在结构中的位置,而无需再次阅读源代码。我刚刚编辑了这个问题,“我在哪里”是什么意思?如何解析?你必须明确,否则这将是一个无人能解决的问题。更新了问题;)对我来说,OP只是想看到一个总是被访问为[basepointer+fieldoffset]的结构,其中basepointer是第一个字段的地址。@MarcoVandevort:这是。我已经做过了,但它要求我在“#”之后进行解析。总比没有好,但还是不行ideal@Larry我不认为你能做得更好,特别是考虑到现代编译器并没有为每个变量都提供一个固定的地址;我会给你提出的解决方案打分,即使我已经这么做了。;)@拉里,如果你觉得这个问题还没有解决,不要认为这是被接受的,所以其他人知道仍然有不同的方法感兴趣。然而,我相信你找到其他东西的机会很小。也可以考虑使用CLANG。在我看来,它生成了更具可读性的汇编。我尝试了clang,但它并没有输出更好的汇编来帮助我:(我想我会保留你的答案。我想如果你在回答中首先建议fverbose asm,那将是非常棒的,因为它有助于解决问题。这可能是最接近的事情,而无需大规模的重新设计:)
settest:
    movl    %edi, test(%rip)
    movl    %esi, test+4(%rip)
    ret

    .comm   test,8,4