首页 > 解决方案 > 如何在汇编中访问 C 结构值?

问题描述

当我想在汇编中访问 C 结构中的某些值时,我通常只是在结构的地址中添加一些东西。但是,当这个结构很大时,它有点累......有没有什么技巧或正常的选择来声明全局标签?

如何在汇编中访问 C 结构值?

标签: cassemblyx86nasm

解决方案


要获取各个成员的地址,就像您正确指出的那样,您必须在结构的地址上添加一个常量偏移量。问题本质上归结为自动计算给定结构和成员的这些偏移量。

即使对于小型结构,我也建议不要手动计算偏移量,因为编译器会在成员之间添加不同的填充,并且提示__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;
}

在构建期间执行这个程序会生成一个可以直接包含在 GASM 中的头文件。对于其他汇编器,您可以更改语法以生成适当的 inc 文件。

这种方法的好处是程序使用与 C/C++ 代码相同的标头。这样,当您更改任何标题时,生成的偏移量应该会自动更改。

您必须在这里注意的一件事是,如果您针对不同的体系结构进行交叉编译并且编译器在您的主机和目标上使用不同的布局,则此技术不能很好地工作。如果您想要类似的交叉编译,我可以写一个单独的答案。


推荐阅读