Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: GNU as: как описать union?
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > GNU/OpenSource средства разработки
Сергей Борщ
Итак, имеем 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 - будут неприятности). Возможно есть все же какое-то красивое решение?
Diz
Если 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

Естественно, все автоматизируется через мейкфайл.
ReAl
Цитата(Сергей Борщ @ Mar 27 2009, 19:48) *
Возможно есть все же какое-то красивое решение?
Ну насколько красивое - решать обществу smile.gif
Ещё в теме про структуры хотел отписаться, родил тогда "ручной" вариант, но не дописал макросы.
Во:
main.S
Код
.nolist
#include <avr/io.h>
.list

.macro struct_start name
\name\()_begin:
.endm

.macro struct_field name, fldname, size
.set \name\()_\fldname, . - \name\()_begin
    .skip \size
.endm

.macro struct_end name
.set \name\()_size , . - \name\()_begin
.endm

.macro set_max name, val1, val2
    .if \val1 > \val2
    .set \name, \val1
    .else
    .set \name, \val2
    .endif
.endm


    .section    .structs,"",@nobits
    struct_start A
    struct_field A, a, 2
    struct_field A, b, 1
    struct_field A, c, 2
    struct_end    A

    struct_start B
    struct_field B, d, 1
    struct_field B, e, 2
    struct_field B, f, 1
    struct_end    B

    set_max AB_size, A_size, B_size


    .data
union1:    .skip AB_size
union2:    .skip AB_size

    .text
    .global main
main:
    lds    R16, union1+A_b
    ldi    ZL, lo8(union2)
    ldi    ZH, hi8(union2)
    ldd    R0, Z+B_e
    ldd    R1, Z+B_e+1
    
    .end

elf-dump (.data пошло с 0x60):
Код
00000038 <main>:
  38:    00 91 62 00     lds    r16, 0x0062
  3c:    e5 e6           ldi    r30, 0x65; 101
  3e:    f0 e0           ldi    r31, 0x00; 0
  40:    01 80           ldd    r0, Z+1; 0x01
  42:    12 80           ldd    r1, Z+2; 0x02

00000044 <_exit>:
  44:    ff cf           rjmp    .-2     ; 0x44 <_exit>

Пойдёт? ;-)
Пописать, чтоли, на ассемблере...

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


Цитата(ReAl @ Mar 29 2009, 00:51) *
Ну насколько красивое - решать обществу
Афигеть! Собственно, другими словами и не выразить. Спасибо огромное! То, что нужно.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.