На ассемблере, как вы справляетесь с C struct? - PullRequest
8 голосов
/ 01 июля 2011

Например, как подготовить параметры для этого syscall sys_wait4:

 asmlinkage long sys_wait4(pid_t pid,unsigned int __user *stat_addr, int options, struct rusage __user *ru)
1120 {

Как работать с struct rusage в сборке?

Привет, мирмне достаточно примера разобраться с struct в сборке:)

1 Ответ

12 голосов
/ 01 июля 2011

Члены struct располагаются последовательно в памяти, возможно, с отступом, и адрес структуры обычно является адресом его первого члена.

struct Bar {
    int x;
    int y;
};

struct Foo {
    struct Bar b;
    double d;
    int i;
};

struct Foo f;

Допустим, что &f это 0x10.Тогда &f.b.x (первый член первого члена Foo) также равен 0x10.&f.b.y - это 0x14, поскольку f.b.x - это четыре байта (в предположении 32-разрядного компьютера).&f.d равно 0x18, а &f.i равно 0x20.Первый адрес, который не занят f (другими словами, &f + 1): 0x24.

Поэтому все, что вам нужно сделать в сборке, это убедиться, что у вас есть (стек или куча)) пространство для членов структуры, и заполните пространство соответствующими данными и передайте адрес первого члена функции.

Что касается примера, который на самом деле включает сборку, вы можете легко создать это самостоятельнонаписав небольшую тестовую программу и скомпилировав ее с gcc -S -O0 -g, вы получите ассемблерный код для вашего C-кода.Например:

int func(struct Foo * foo) {
    return foo->b.x + foo->i;
}

int main() {
    struct Foo foo;
    foo.b.x = 42;
    foo.b.y = 9;
    foo.d = 3.14;
    foo.i = 8;
    func(&foo);
    return 0;
}

В выводе сборки, помимо прочего, вы увидите (обратите внимание: это 64-битный ASM):

movl    $42, -32(%rbp)
movl    $9, -28(%rbp)
movabsq $4614253070214989087, %rax
movq    %rax, -24(%rbp)
movl    $8, -16(%rbp)

Как видите,значения 42, 9 (целое число, битовая комбинация которого равна 3,14) и 8 загружаются в адреса -32, -28, -24 и -16 (относительно базового указателя).У меня под рукой есть только окно Solaris, поэтому я не смог использовать asmlinkage (который указывает, что аргументы функции должны передаваться в стеке, а не в регистрах), поэтому непосредственно перед вызовом функции мы видим эффективный адресструктура загружается в регистр:

leaq    -32(%rbp), %rax
movq    %rax, %rdi

С asmlinkage вы вместо этого увидите эффективный адрес, помещаемый в стек.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...