gcc-作为调试标签的结构 背景:
Linux 64 我想要一种方法,告诉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)
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