如何确定从程序集调用的 stat 结构体中的字段偏移量?

问题描述 投票:0回答:2

为了获得描述文件的

struct stat
,我们可以调用 *stat 系列函数,这些函数将用结构值填充传递的指针所指向的内存。

C中我们可以调用POSIX.1-2008offsetof宏,但它是一个宏,在汇编中不可用。

如何从程序集中确定结构体的大小以及如何确定字段的偏移量,以便可以提取必要的字段,例如

st_size
st_mode
等?

assembly struct offset abi stat
2个回答
3
投票

平台的 ABI 决定了 C 结构体填充的规则。例如,x86-64 Linux 使用 x86-64 System V ABI

困难的方法:阅读 ABI 并自己解决。 标签 wiki 中的链接。 (实际上并不那么难,结构内的对齐/填充规则对于 x86-64 System V ABI 来说非常简单:每个成员都按声明顺序排列,并且自然对齐。这可能需要填充。Windows x64 有自己的结构布局规则并不总是产生相同的布局。)

简单的方法:让编译器通过编写一个存储到结构体中的函数来计算偏移量,然后查看 asm.h 文件。例如

#include <sys/stat.h>
void foo(struct stat *st) {
    st->st_size = 1;
    st->st_mode = 2;  // different numbers so you know which field is which in the output
}

    mov     QWORD PTR [rdi+48], 1
    mov     DWORD PTR [rdi+24], 2
    ret

(来自 Godbolt 编译器浏览器


让编译器输出常量在单独的 .asm / .S 中使用

查看其他一些问答,其中的答案旨在自动化生成定义的过程,例如

#define
.equ
,或 NASM
equ
:


1
投票

在这种情况下,使用 templated 内联汇编器部分并以

offsetof(...)
作为输入参数来编写 C 模块可能会更容易:

#include <stddef.h>
#include <sys/stat.h>

int my_function(int arg0, void *arg1) {
    int result;
    __asm__(
        "some_command %[a0], %[a1], %[mode_offset]"
        :   [result] "=r"(result)
        :   [a0] "r"(arg0), [a1] "r"(arg1), 
            [mode_offset] "ri"(offsetof(struct stat, st_mode))
        : "cc");
    return result;
}
© www.soinside.com 2019 - 2024. All rights reserved.