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

 
 
> Возврат структуры, Чисто теоретический вопрос...
demiurg_spb
сообщение Jun 3 2009, 17:34
Сообщение #1


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Возник вопросик. Хочу уяснить для себя кое-что.
Компилятор: avr-gcc (WinAVR 20090313) 4.3.2.

Тест1 - размер структуры 7 байт и компилятор возвращает её через регистры - размер прошивки 60518 байт.
Код
typedef struct
{
    unsigned char sec;
    unsigned char min;
    unsigned char hour;
    unsigned char sec_div10;  // десятые секунды.
    unsigned char dat;        // день месяца.  
    unsigned char month;
    unsigned char year;       // 0 = 2000
} rtc_t;


Тест2 - размер структуры 39 байт и компилятор возвращает её через стек??? - размер прошивки 60088 байт (значительно компактней!!!).
Код
typedef struct
{
    unsigned char sec;
    unsigned char min;
    unsigned char hour;
    unsigned char sec_div10;  // десятые секунды.
    unsigned char dat;        // день месяца.  
    unsigned char month;
    unsigned char year;       // 0 = 2000
    unsigned char dummy[32];
} rtc_t;

Исходник:
Код
//=============================================================================
rtc_t dffs_get_page_start_time(unsigned short page)
{
    rtc_t rtc;

    df_read_to(page, DFFS_RTC_OFFSET, sizeof(rtc_t), &rtc);

    return (rtc);
}

Есть два вопроса. Прошу не пинать (я знаю что можно возвращать указатель) вопросы только для самообразования.

1. как работает механизм передачи больших структур (если при выходе из неё я вижу полную раскрутку стека обратно)?
2. как принудить компилятор возвращать структуры через стек (если это так, пока я не понял).

Листинг варианта1:
Код
//=============================================================================
rtc_t dffs_get_page_start_time(unsigned short page)
{
    b488:    2f 92           push    r2
    b48a:    3f 92           push    r3
    b48c:    4f 92           push    r4
    b48e:    5f 92           push    r5
    b490:    6f 92           push    r6
    b492:    7f 92           push    r7
    b494:    8f 92           push    r8
    b496:    9f 92           push    r9
    b498:    af 92           push    r10
    b49a:    bf 92           push    r11
    b49c:    cf 92           push    r12
    b49e:    df 92           push    r13
    b4a0:    ef 92           push    r14
    b4a2:    ff 92           push    r15
    b4a4:    0f 93           push    r16
    b4a6:    1f 93           push    r17
    b4a8:    df 93           push    r29
    b4aa:    cf 93           push    r28
    b4ac:    cd b7           in    r28, 0x3d; 61
    b4ae:    de b7           in    r29, 0x3e; 62
    b4b0:    2e 97           sbiw    r28, 0x0e; 14
    b4b2:    0f b6           in    r0, 0x3f; 63
    b4b4:    f8 94           cli
    b4b6:    de bf           out    0x3e, r29; 62
    b4b8:    0f be           out    0x3f, r0; 63
    b4ba:    cd bf           out    0x3d, r28; 61
    rtc_t rtc;

    df_read_to(page, DFFS_RTC_OFFSET, sizeof(rtc_t), &rtc);
    b4bc:    63 e0           ldi    r22, 0x03; 3
    b4be:    70 e0           ldi    r23, 0x00; 0
    b4c0:    47 e0           ldi    r20, 0x07; 7
    b4c2:    8e 01           movw    r16, r28
    b4c4:    0f 5f           subi    r16, 0xFF; 255
    b4c6:    1f 4f           sbci    r17, 0xFF; 255
    b4c8:    98 01           movw    r18, r16
    b4ca:    0e 94 b2 29     call    0x5364; 0x5364 <df_read_to>

    return (rtc);
    b4ce:    de 01           movw    r26, r28
    b4d0:    18 96           adiw    r26, 0x08; 8
    b4d2:    f8 01           movw    r30, r16
    b4d4:    87 e0           ldi    r24, 0x07; 7
    b4d6:    01 90           ld    r0, Z+
    b4d8:    0d 92           st    X+, r0
    b4da:    81 50           subi    r24, 0x01; 1
    b4dc:    e1 f7           brne    .-8; 0xb4d6 <dffs_get_page_start_time+0x4e>
    b4de:    8e 85           ldd    r24, Y+14; 0x0e
    b4e0:    99 24           eor    r9, r9
    b4e2:    28 84           ldd    r2, Y+8; 0x08
    b4e4:    39 84           ldd    r3, Y+9; 0x09
    b4e6:    4a 84           ldd    r4, Y+10; 0x0a
    b4e8:    5b 84           ldd    r5, Y+11; 0x0b
    b4ea:    6c 84           ldd    r6, Y+12; 0x0c
    b4ec:    7d 84           ldd    r7, Y+13; 0x0d
    b4ee:    51 01           movw    r10, r2
    b4f0:    62 01           movw    r12, r4
    b4f2:    73 01           movw    r14, r6
}
    b4f4:    95 01           movw    r18, r10
    b4f6:    a6 01           movw    r20, r12
    b4f8:    b7 01           movw    r22, r14
    b4fa:    99 2d           mov    r25, r9
    b4fc:    2e 96           adiw    r28, 0x0e; 14
    b4fe:    0f b6           in    r0, 0x3f; 63
    b500:    f8 94           cli
    b502:    de bf           out    0x3e, r29; 62
    b504:    0f be           out    0x3f, r0; 63
    b506:    cd bf           out    0x3d, r28; 61
    b508:    cf 91           pop    r28
    b50a:    df 91           pop    r29
    b50c:    1f 91           pop    r17
    b50e:    0f 91           pop    r16
    b510:    ff 90           pop    r15
    b512:    ef 90           pop    r14
    b514:    df 90           pop    r13
    b516:    cf 90           pop    r12
    b518:    bf 90           pop    r11
    b51a:    af 90           pop    r10
    b51c:    9f 90           pop    r9
    b51e:    8f 90           pop    r8
    b520:    7f 90           pop    r7
    b522:    6f 90           pop    r6
    b524:    5f 90           pop    r5
    b526:    4f 90           pop    r4
    b528:    3f 90           pop    r3
    b52a:    2f 90           pop    r2
    b52c:    08 95           ret

Видно что он резервирует на стеке вдвое больше памяти чем надо (14 байт вместо 7) потом тупо копирует одно в другое (из одной половинки 14-и байтного участка памяти в другую), потом читает вторую область памяти во временные регистры, потом копирует их содержимое в нужные регистры. Короче мрачняк...

Листинг варианта2:
Код
//=============================================================================
rtc_t dffs_get_page_start_time(unsigned short page)
{
    b476:    ef 92           push    r14
    b478:    ff 92           push    r15
    b47a:    0f 93           push    r16
    b47c:    1f 93           push    r17
    b47e:    df 93           push    r29
    b480:    cf 93           push    r28
    b482:    cd b7           in    r28, 0x3d; 61
    b484:    de b7           in    r29, 0x3e; 62
    b486:    a7 97           sbiw    r28, 0x27; 39
    b488:    0f b6           in    r0, 0x3f; 63
    b48a:    f8 94           cli
    b48c:    de bf           out    0x3e, r29; 62
    b48e:    0f be           out    0x3f, r0; 63
    b490:    cd bf           out    0x3d, r28; 61
    b492:    7c 01           movw    r14, r24
    b494:    cb 01           movw    r24, r22
    rtc_t rtc;

    df_read_to(page, DFFS_RTC_OFFSET, sizeof(rtc_t), &rtc);
    b496:    63 e0           ldi    r22, 0x03; 3
    b498:    70 e0           ldi    r23, 0x00; 0
    b49a:    47 e2           ldi    r20, 0x27; 39
    b49c:    8e 01           movw    r16, r28
    b49e:    0f 5f           subi    r16, 0xFF; 255
    b4a0:    1f 4f           sbci    r17, 0xFF; 255
    b4a2:    98 01           movw    r18, r16
    b4a4:    0e 94 b2 29     call    0x5364; 0x5364 <df_read_to>

    return (rtc);
    b4a8:    d7 01           movw    r26, r14
    b4aa:    f8 01           movw    r30, r16
    b4ac:    87 e2           ldi    r24, 0x27; 39
    b4ae:    01 90           ld    r0, Z+
    b4b0:    0d 92           st    X+, r0
    b4b2:    81 50           subi    r24, 0x01; 1
    b4b4:    e1 f7           brne    .-8; 0xb4ae <dffs_get_page_start_time+0x38>
}
    b4b6:    c7 01           movw    r24, r14
    b4b8:    a7 96           adiw    r28, 0x27; 39
    b4ba:    0f b6           in    r0, 0x3f; 63
    b4bc:    f8 94           cli
    b4be:    de bf           out    0x3e, r29; 62
    b4c0:    0f be           out    0x3f, r0; 63
    b4c2:    cd bf           out    0x3d, r28; 61
    b4c4:    cf 91           pop    r28
    b4c6:    df 91           pop    r29
    b4c8:    1f 91           pop    r17
    b4ca:    0f 91           pop    r16
    b4cc:    ff 90           pop    r15
    b4ce:    ef 90           pop    r14
    b4d0:    08 95           ret

Тут всё красиво, но не понимаю как оно работает!!!
Прошу прощения за длинное сообщение - не понял как создать окошко со скроллером.

И ещё, никогда не пробовал, так и не знал, что можно присваивать структуру структуреsmile.gif
Код
rtc_t rtc1 = {0};
rtc_t rtc2;
....
rtc1 = rtc2; // и без всяких memcpy (здорово, код получается компактный с однобайтным счётчиком цикла!)


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
ukpyr
сообщение Jun 4 2009, 06:34
Сообщение #2


Профессионал
*****

Группа: Участник
Сообщений: 1 264
Регистрация: 17-06-08
Из: бандустан
Пользователь №: 38 347



автор, вы перешли на С с Паскаля, нет ?
почитайте документацию на AVR_GCC, в каких регистрах передаются параметры/результаты.
возвращение результата-структуры через стек - мягко говоря странно и неэффективно для АВР.
чем указатели не угодили ? просто объявите внутреннюю структуру static и возвращайте указатель на нее.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Jun 4 2009, 11:32
Сообщение #3


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



ukpyr, я же изначально просил не поднимать флейм, а Ваше сообщение абсолютно бессмысленно.
ReAl и Сергей, спасибо за разъяснения! Всё встало на свои местаsmile.gif
Осталось найти и опции компилятора (если они существуют), которые определяют максимальный размер возвращаемого параметра при котором он будет передан не через регистры а через стек. Мне действительно нужна реентерабельность функции и в тоже время логичность и простота...
Тогда получается что во втором варианте компилятор поступает неразумно, опять выделяет место на стеке под локальную переменную, вместо того, чтобы сразу использовать область памяти полученную через указатель скрытым аргументом. Опять обидно... Может есть способ обойти это?


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
_Pasha
сообщение Jun 6 2009, 16:08
Сообщение #4


;
******

Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509



Цитата(demiurg_spb @ Jun 4 2009, 14:32) *
...размер возвращаемого параметра при котором он будет передан не через регистры а через стек. Мне действительно нужна реентерабельность функции ...

Уже проясняли этот вопрос: реентерабельность не зависит от того, каким макаком передали параметры- через регистры или через стек. Потому что при переключении процессов регистры ведь сохраняются...
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- demiurg_spb   Возврат структуры   Jun 3 2009, 17:34
- - ReAl   Цитата(demiurg_spb @ Jun 3 2009, 20:34) 1...   Jun 3 2009, 18:34
- - sergeeff   Какие-то "странноватые" задачи вы сами с...   Jun 3 2009, 19:19
- - ReAl   В первую очередь это более понятный код. Говорим/д...   Jun 3 2009, 20:24
|- - sergeeff   Цитата(ReAl @ Jun 3 2009, 23:24) В первую...   Jun 4 2009, 06:06
|- - ReAl   Цитата(sergeeff @ Jun 4 2009, 09:06) Чем ...   Jun 4 2009, 15:02
|- - AHTOXA   Цитата(demiurg_spb @ Jun 4 2009, 17:32) М...   Jun 4 2009, 12:08
||- - sergeeff   Цитата(AHTOXA @ Jun 4 2009, 15:08) Способ...   Jun 4 2009, 12:17
|- - demiurg_spb   Цитата(_Pasha @ Jun 6 2009, 20:08) Уже пр...   Jun 7 2009, 16:44
- - _Pasha   Возвращать структуры через стек опасно по причине ...   Jun 4 2009, 06:59
|- - Сергей Борщ   Цитата(_Pasha @ Jun 4 2009, 09:59) Возвра...   Jun 4 2009, 07:27
|- - _Pasha   Цитата(Сергей Борщ @ Jun 4 2009, 10:27) А...   Jun 4 2009, 07:40
|- - sergeeff   Цитата(_Pasha @ Jun 4 2009, 10:40) Не-не-...   Jun 4 2009, 07:53
|- - _Pasha   Цитата(sergeeff @ Jun 4 2009, 10:53) Тем ...   Jun 4 2009, 08:00
|- - Сергей Борщ   Цитата(_Pasha @ Jun 4 2009, 11:00) Может ...   Jun 4 2009, 08:08
- - _Pasha   Цитата(Сергей Борщ @ Jun 4 2009, 11:08)  ...   Jun 4 2009, 08:21
|- - sergeeff   Цитата(_Pasha @ Jun 4 2009, 11:21) Спасиб...   Jun 4 2009, 11:34
- - sergeeff   Я лично очень рад, что вам все понятно. Зачем тогд...   Jun 4 2009, 15:16
- - ReAl   Цитата(sergeeff @ Jun 4 2009, 18:16) Я ли...   Jun 4 2009, 15:47
- - sergeeff   Цитата(ReAl @ Jun 4 2009, 18:47) Какие во...   Jun 4 2009, 16:17


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

 


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


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