要获取各个成员的地址,就像您正确指出的那样,您必须向结构的地址添加一个常量偏移量。问题本质上归结为自动计算给定结构和成员的这些偏移量。
即使对于小型结构,我建议不要手动计算偏移量,因为编译器会在成员和提示之间添加不同的填充,例如__attribute__(packed)并非所有编译器都可用。
对于我的大多数项目,我使用单独的程序在构建时生成偏移标头。
基本思想是创建一个.c/.cpp包含以下内容的文件 -
// Your program headers that define the structs here
#include <stdio.h>
#include <stddef.h>
#define OFFSET(x, str, mem) printf("#define " #x " %d\n",(int) offsetof(str, mem))
#define SIZE(x, str) printf("#define " #x " %d\n", (int) sizeof(str))
#define HEADER_START() printf("#ifndef ASM_OFFSET_H\n#define ASM_OFFSET_H\n")
#define HEADER_END() printf("#endif\n")
int main(int argc, char *argv[]) {
HEADER_START();
OFFSET(struct_name_member_name, struct_name, member_name); // Substitute your struct name and member name here
SIZE(struct_name_size, struct_name); // This macro is to get the size of a struct
HEADER_END();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在构建期间执行该程序会生成一个可以直接包含在 GASM 中的头文件。对于其他汇编器,您可以更改语法以生成适当的 inc 文件。
这种方法的好处是程序使用与 C/C++ 代码相同的标头。这样,当您更改任何标题时,生成的偏移量应该自动更改。
这里必须小心的一件事是,如果您针对不同的体系结构进行交叉编译并且编译器在主机与目标上使用不同的布局,则该技术无法正常工作。如果您想要类似的交叉编译,我可以写一个单独的答案。