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

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> Снова о gcc и невыровненном доступе к памяти
KRS
сообщение Jun 28 2011, 13:51
Сообщение #16


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

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(Petka @ Jun 28 2011, 17:46) *
Так понятней?

Да все было и так понятно! Не понятно зачем городить этот огород, не проще ли взять современный компилятор и объяснить ему что, где и в каком порядке лежит! Тогда код будет и понятнее и оптимальнее wink.gif потому что есть инструкции чтения с переворотом и т.п.

Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 28 2011, 14:05
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (Petka @ Jun 28 2011, 15:46) *
Так понятней?

KRS все уже объяснил, почему делать так, как Вы сделали, неразумно.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Petka
сообщение Jun 28 2011, 14:46
Сообщение #18


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

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



Цитата(KRS @ Jun 28 2011, 17:51) *
Да все было и так понятно! Не понятно зачем городить этот огород, не проще ли взять современный компилятор и объяснить ему что, где и в каком порядке лежит! Тогда код будет и понятнее и оптимальнее wink.gif потому что есть инструкции чтения с переворотом и т.п.

Прошу в студию код, как "правильно" объявить структуру blabla у ТС для gcc.

Цитата(zltigo @ Jun 28 2011, 18:05) *
KRS все уже объяснил, почему делать так, как Вы сделали, неразумно.

Только что проверил.
Код
     uint8_t msg[]  __attribute__ ((aligned (16))) =
        { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A };

    struct blabla_t {
        char ch;
        int that __attribute__((packed));
    } __attribute__((packed));
    
    struct blabla_t *bla;

    int a;

    bla=&msg[3];
    a = bla->that;
    printf("a = 0x%08X\n", a);

    bla=&msg[0];
    a = bla->that;
    printf("a = 0x%08X\n", a);


результат:

Код
a = 0x08070605
Ошибка шины


Итог: никакие "#pragma packed" вам не помогут!
Вот теперь понятно?

P.S.
Я включил в системе контроль alignment.
"Ошибка шины" это "SIGBUS" - и есть ошибка невыровненного доступа.
Go to the top of the page
 
+Quote Post
KRS
сообщение Jun 28 2011, 15:22
Сообщение #19


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

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(Petka @ Jun 28 2011, 18:46) *
Итог: никакие "#pragma packed" вам не помогут!
Вот теперь понятно?

Ну вам не помогают, а мне помогают

Код
#include <stdint.h>
#include <stdio.h>

#pragma pack(1)
typedef struct {
    char ch;
    int that;
} blabla_t;
#pragma pack()

void test(blabla_t *bla)
{
    printf("a = 0x%08X\n", bla->that);
}

uint8_t msg[]  __attribute__ ((aligned (16))) =
        { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A };
void test2(void)
{
    blabla_t *bla;

    int a;

    bla= (blabla_t *)&msg[3];
    a = bla->that;
    printf("a = 0x%08X\n", a);

    bla=(blabla_t *)&msg[0];
    a = bla->that;
    printf("a = 0x%08X\n", a);
}


По листингу все читается по байтам, так что все ок!
Все таки надо использовать typedef и при присваивании преобразовывать указатели, что бы не плодить warningи, на которые стоит обращать внимание!

Go to the top of the page
 
+Quote Post
Petka
сообщение Jun 28 2011, 16:00
Сообщение #20


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

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



Цитата(KRS @ Jun 28 2011, 19:22) *
Ну вам не помогают, а мне помогают
....
По листингу все читается по байтам, так что все ок!
Все таки надо использовать typedef и при присваивании преобразовывать указатели, что бы не плодить warningи, на которые стоит обращать внимание!

Давайте разбираться:
Собрал ваш код gcc (4.5.2, "-O0"). Ошибка доступа ЕСТЬ!
Код
objdump -d -S ./a.out


Вывод:
Код
080483e3 <test2>:

uint8_t msg[]  __attribute__ ((aligned (16))) =
        { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A };

void test2(void)
{
80483e3:    55                       push   %ebp
80483e4:    89 e5                    mov    %esp,%ebp
80483e6:    83 ec 28                 sub    $0x28,%esp
    blabla_t *bla;

    int a;

    bla= (blabla_t *)&msg[3];
80483e9:    b8 20 a0 04 08           mov    $0x804a020,%eax
80483ee:    83 c0 03                 add    $0x3,%eax
80483f1:    89 45 f4                 mov    %eax,-0xc(%ebp)
    a = bla->that;
80483f4:    8b 45 f4                 mov    -0xc(%ebp),%eax
80483f7:    8b 40 01                 mov    0x1(%eax),%eax
80483fa:    89 45 f0                 mov    %eax,-0x10(%ebp)
    printf("a = 0x%08X\n", a);
80483fd:    b8 20 85 04 08           mov    $0x8048520,%eax
8048402:    8b 55 f0                 mov    -0x10(%ebp),%edx
8048405:    89 54 24 04              mov    %edx,0x4(%esp)
8048409:    89 04 24                 mov    %eax,(%esp)
804840c:    e8 e3 fe ff ff           call   80482f4 <printf@plt>

    bla=(blabla_t *)&msg[0];
8048411:    c7 45 f4 20 a0 04 08     movl   $0x804a020,-0xc(%ebp)
    a = bla->that;
8048418:    8b 45 f4                 mov    -0xc(%ebp),%eax
804841b:    8b 40 01                 mov    0x1(%eax),%eax
804841e:    89 45 f0                 mov    %eax,-0x10(%ebp)
    printf("a = 0x%08X\n", a);
8048421:    b8 20 85 04 08           mov    $0x8048520,%eax
8048426:    8b 55 f0                 mov    -0x10(%ebp),%edx
8048429:    89 54 24 04              mov    %edx,0x4(%esp)
804842d:    89 04 24                 mov    %eax,(%esp)
8048430:    e8 bf fe ff ff           call   80482f4 <printf@plt>
}
8048435:    c9                       leave  
8048436:    c3                       ret

И где тут по-байтное обращение?
Go to the top of the page
 
+Quote Post
KRS
сообщение Jun 28 2011, 16:05
Сообщение #21


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

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(Petka @ Jun 28 2011, 20:00) *
Давайте разбираться:
Собрал ваш код gcc (4.5.2). Ошибка доступа ЕСТЬ!

И при чем здесь ARM?
Интел умеет читать по не выравненному адресу, зачем читать по байтам?

Go to the top of the page
 
+Quote Post
Petka
сообщение Jun 28 2011, 16:18
Сообщение #22


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

Группа: Свой
Сообщений: 1 453
Регистрация: 23-08-05
Пользователь №: 7 886



Цитата(KRS @ Jun 28 2011, 20:05) *
И при чем здесь ARM?
Интел умеет читать по не выравненному адресу, зачем читать по байтам?

Может, но не обязан. (См. eFlags, бит 18)

Цитата(KRS @ Jun 28 2011, 20:05) *
И при чем здесь ARM?

Да, проверил на ARM. Действительно читает по-байтно.

P.S. Вот бы ещё ссылку на стандарт какой.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jun 28 2011, 16:54
Сообщение #23


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (Petka @ Jun 28 2011, 18:18) *
P.S. Вот бы ещё ссылку на стандарт какой.

Причем тут стандарт? Что Вы хотите увидеть? Большими красными буквами "Компилятор языка 'C' обязан уметь корректно работать со структурами данных"?
Есть структура данных, Вы полно и корректно описали, что она из себя представляет. Все, любой компилятор обязан правильно работать.
Зачем указывать отдельно, например, в ГОСТ на автомобиль, то, что должен уметь перемещаться и без запряженной лошади? И уж тем более, не стоит ее в автомобиль запрягать,
даже если в ГОСТ на него не написано, что лошадь не требуется.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
KRS
сообщение Jun 28 2011, 17:36
Сообщение #24


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

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Цитата(Petka @ Jun 28 2011, 20:18) *
Да, проверил на ARM. Действительно читает по-байтно.

А хороший компилер, в случае с
bla= (blabla_t *)&msg[3];
a = bla->that;
должен читать сразу слово! (при соотв. уровне оптимизации) потому что в данном случае возможно проследить выравнивание. И, например, RVCT так и делает!
Go to the top of the page
 
+Quote Post
VladislavS
сообщение Jun 28 2011, 17:43
Сообщение #25


Местный
***

Группа: Свой
Сообщений: 475
Регистрация: 14-04-05
Из: Москва
Пользователь №: 4 140



Если компилятор сам расположил структуру в памяти, то вне зависимости от директивы pack он должен корректно обращаться к памяти при доступе к любому полю.

А вот если с указателями работать вольно, то запросто можно схлопотать ошибку доступа. Или вот так sm.gif

Код
*((int *)0x40000007)=0;
Go to the top of the page
 
+Quote Post

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

 


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


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