如何以可维护和可读的方式在ARM程序集中重用C结构?

时间:2014-03-05 00:04:22

标签: c assembly struct arm

访问struct字段时,我一直在手动向地址添加偏移量以访问字段。这非常繁琐,难以阅读和维护问题。

有没有更好的方法来访问C结构字段?

例如,我正在考虑这样的语法:

example.h文件: typedef struct { int a; int b; } MyStruct;

example.s: ldr r1, [r2, #MyStruct.b] // r2 contains an address to a MyStruct

2 个答案:

答案 0 :(得分:6)

实际上没有干净便携的方式。我见过的大多数项目都有一些构建步骤,可以生成struct offsets的头文件。它有点像这样:

1)创建一个定义偏移量的C文件

#include "mystruct.h"

#define DECLARE(SYM,VAL) \
__asm("__AS_DEFINE__ " SYM "\t%0" : : "n" ((unsigned long)(VAL)))

void foo(void)
{
    // mystruct.h
    DECLARE("MYSTRUCT_B",  offsetof(struct mystruct, b));
}

2)使用标志编译该文件以生成程序集(Clang或GCC上的-S)。这将创建一个包含一堆已定义行的汇编文件,例如:

    __AS_DEFINE__ MYSTRUCT_B    #4

3)使用一些shell技巧将它们变成汇编代码的头文件。

grep '__AS_DEFINE__' offsets.s | sed 's/#//g' | sed 's/__AS_DEFINE__/#define/g' > build/include/offsets.h

这会生成一个看起来像这样的文件,并且可以包含在您的程序集源中。

    #define MYSTRUCT_B  4

然后您可以直接使用它。

#include "offsets.h"

    ldr r1, [r2, #MYSTRUCT_B]

答案 1 :(得分:1)

    $coupon->product_restriction = 1; //enable product restriction

    $coupon->reduction_product = -2; // write this only if you want the discount to be applied on the products in the cart and not the whole cart

    (new Cart( $cart->id) )->addCartRule( (int) $cartRuleId); // apply the cart rule to this existing cart

    # first, save `id_cart_rule` & `quantity` and get id_product_rule_group
    Db::getInstance()->execute('INSERT INTO `'._DB_PREFIX_.'cart_rule_product_rule_group` (`id_cart_rule`, `quantity`)
    VALUES ('.(int)$cartRuleId.', "'.(int)$qty.'")');
    $id_product_rule_group = Db::getInstance()->Insert_ID();

    # second, save `id_product_rule_group` & `type` and get id_product_rule
    Db::getInstance()->execute('INSERT INTO `'._DB_PREFIX_.'cart_rule_product_rule` (`id_product_rule_group`, `type`)
    VALUES ('.(int)$id_product_rule_group.', "'.$type.'")');
    $id_product_rule = Db::getInstance()->Insert_ID();

    # finally, using id_product_rule assign products
    foreach ($products as $id) {
        $values[] = '('.(int)$id_product_rule.','.(int)$id.')';
    }
    $values = array_unique($values);
    if (count($values)) {
        Db::getInstance()->execute('INSERT INTO `'._DB_PREFIX_.'cart_rule_product_rule_value` (`id_product_rule`, `id_item`) VALUES '.implode(',', $values));
    }