реклама на сайте
подробности

 
 
> GNU as: как описать union?, Что-то не придумывается.
Сергей Борщ
сообщение Mar 27 2009, 17:48
Сообщение #1


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Итак, имеем union, описанный на С примерно так:
Код
union a_t
    {
        struct
        {
            uint16_t    a;
            uint8_t     b;
            uint16_t    c;
        };
        struct
        {
            uint8_t     d;
            uint16_t    e;
            uint8_t     f;
        };
    } A;
Для ИАРа делается просто:
Код
    RSEG MYDATA : DATA(0)
    A:
    a   DS  2
    b   DS  1
    c   DS  2
        ORG 0
    d   DS  1
    e   DS  2
    f   DS  1
    
    теперь
      LDI R30, LOW(A)
      LDI R31, HIGH(A)
      LD  R16, Z+ (a - A) + 0
      LD  R17, Z+ (a - A) + 1
      LD  R18, Z+ (b - A)
А у гнутого асма .org работает иначе, им нельзя сдвинуть location counter назад и как мне организовать что-то эквивалентное - не могу придумать. Делать
Код
A:
      .skip 4,0
      .set  a, A + 0
      .set  b, a + 2
      .set  c, b + 1
      .set  d, A + 0
      .set  e, d + 1
      .set  f, e + 2
не хочется, ибо и размеры переменных неочевидны и нет автоматического резервирования места (если добавить переменную и забыть исправить .skip - будут неприятности). Возможно есть все же какое-то красивое решение?


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Diz
сообщение Mar 28 2009, 12:11
Сообщение #2


Частый гость
**

Группа: Участник
Сообщений: 84
Регистрация: 1-08-06
Пользователь №: 19 250



Если union объявляется в C, и к нему нужен доступ из ассемблера (с вычислением оффсетов переменных), стоит сделать так.

Код
/** Nick Stephen's trick to get info from C-file */
#define DECLARE(SYM,VAL) __asm__("\r#define\t" SYM "\t%0" : : "n" ((int)(VAL)))


Создается C-файл для генерации оффсетов

Код
#include "mystruct.h"

void calc_offsets( void)
{
    DECLARE( "A_A",offsetof( a_t, a));
    DECLARE( "A_F",offsetof( a_t, f));
}


Из файла делается ассемблерный листинг, offsets.S (скомпилировать его не удастся по понятным причинам :-)
Затем grep '#define' offsets.S offsets.inc
offsets.inc замечательно включается в ассемблерный исходник и содержит все нужные строчки, типа #define A_A #0

Естественно, все автоматизируется через мейкфайл.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 29 2009, 00:42
Сообщение #3


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Diz @ Mar 28 2009, 14:11) *
стоит сделать так.
Да, мысль пойти от С в голову не приходила, видимо потому что весь проект, для которого это нужно, уже написан на асме (исходно был на С, но в процессе упихивания в 2К области зарузчика асмовые листинги были заоптимизированы напрочь). Решение красивое. Только  я бы в DECLARE генерил просто асмовые директивы .set, получая сразу глобальные символы без всякой пост-обработки.


Цитата(ReAl @ Mar 29 2009, 00:51) *
Ну насколько красивое - решать обществу
Афигеть! Собственно, другими словами и не выразить. Спасибо огромное! То, что нужно.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post



Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 20:00
Рейтинг@Mail.ru


Страница сгенерированна за 0.01358 секунд с 7
ELECTRONIX ©2004-2016