Перейти к содержанию
    

8 минут назад, makc сказал:

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

Значит я не понял, что Вы имели в виду под термином "обращение по адресу к объекту"? Ведь любое обращение к объекту, расположенному в памяти, будет "обращением по адресу". И как тогда может "потеряться связь с объектом"?

PS: Операция взятия адреса объекта - это тоже обращение к объекту.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 минуту назад, jcxz сказал:

Значит я не понял, что Вы имели в виду под термином "обращение по адресу к объекту"? Ведь любое обращение к объекту, расположенному в памяти, будет "обращением по адресу".

Да, но в одном случае обращение будет по имени этого объекта и тогда у компилятора с линкером есть возможность проследить связь с объектом, а в другом нет (при обращении по прямому адресу) и тогда объект может оказаться бесхозным.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 минуту назад, makc сказал:

а в другом нет (при обращении по прямому адресу)

Это как? По абсолютному константному адресу, вычисленному написателем программы? типа: *(int *)0x12345678 ?

В этом случае да, но тут и речи нет ни о каком "обращении к объекту". Да и автора такого безобразия (при обращении к си-объекту) нужно нещадно сечь розгами.  :punish:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Только что, jcxz сказал:

Это как? По абсолютному константному адресу, вычисленному написателем программы? типа: *(int *)0x12345678 ?

Например так. 🙂

1 минуту назад, jcxz сказал:

В этом случае да, но тут и речи нет ни о каком "обращении к объекту". Да и автора такого безобразия (при обращении к си-объекту) нужно нещадно сечь розгами.  :punish:

Полностью согласен, но в жизни встречается всякое...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, makc сказал:

Ну это как сказать... На этом уровне уже нет информации о потоке исполнения команд, а есть только ассемблер.

Линкер собирает программу из объектных файлов. А в них есть вся информация. Т.ч. добыть оттуда имена, типы и прочее — дело техники.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

31 минуту назад, dxp сказал:

Линкер собирает программу из объектных файлов. А в них есть вся информация. Т.ч. добыть оттуда имена, типы и прочее — дело техники.

Типов там нет (они сохраняются только в отладочной информации, если она есть) и линкер ничего не должен про них знать, т.к. они являются более высокоуровневыми атрибутами сущностей языка программирования. Линкер оперирует блоками кода (данных) и ссылками на них по именам символов и более ничем.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, jcxz сказал:

Это как? По абсолютному константному адресу, вычисленному написателем программы? типа: *(int *)0x12345678 ?

Вообще, в жизни так бывает. Например, в заголовочном файле контроллера задефаёнен адрес буфера USB

#define USB_PMAADDR           (APB1PERIPH_BASE + 0x00006000U)

В программе используется так

inline const auto ep_buf_dscr = (volatile EP_BUF_DSCR *)USB_PMAADDR;

ep_buf_dscr[0].ADDR_TX = EP0_ADDR_TX;
ep_buf_dscr[0].COUNT_TX = 0;

Без мэджик намберов, но смысл тот же. volatile буфер есть, но линкер о нем ничего не знает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, jcxz сказал:

Вы уверены? В каком компиляторе/компоновщике?

ARM Compiler 6 (clang + armlink).

u8 flash_isBusy(void) {
  return FLASH->SR & FLASH_SR_BSY;
}

тоже нигде не вызывается, но в map-файле

Цитата

Removing Unused input sections from the image.

...
    Removing flash.o(.text.flash_isBusy), (16 bytes).
    Removing flash.o(.ARM.exidx.text.flash_isBusy), (8 bytes).
...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

19 минут назад, makc сказал:

Типов там нет (они сохраняются только в отладочной информации, если она есть) и линкер ничего не должен про них знать, т.к. они являются более высокоуровневыми атрибутами сущностей языка программирования. Линкер оперирует блоками кода (данных) и ссылками на них по именам символов и более ничем.

Да, типов просто так нет (кроме манглинга для случая С++). Но ведь если к объекту нет обращений вообще, какая разница какого он типа и квалификации (cv)? Не используется, можно выкинуть из памяти, тут погружаться в анализ, что сие есть такое, ни к чему.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

22 часа назад, VladislavS сказал:

Вообще, в жизни так бывает. Например, в заголовочном файле контроллера задефаёнен адрес буфера USB

#define USB_PMAADDR           (APB1PERIPH_BASE + 0x00006000U)

Это другое  :wink:

22 часа назад, VladislavS сказал:

Без мэджик намберов, но смысл тот же. volatile буфер есть, но линкер о нем ничего не знает.

Смысл не "тот же". Разговор шёл о работе с объектом си (переменной/константой) нештатным образом (через её абсолютный адрес). У вас такого объекта нет. Мимо кассы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 05.02.2023 в 19:59, SII сказал:

Проблема возникла из-за того, что компилятор не способен увидеть, что вызов Append может поменять поле First заголовка очереди...

А что насчет -fno-strict-aliasing в опциях компилятора? На уровнях O1 и выше отключится строгий алиасинг и оптимизирующего упреждающего чтения First вместе с Last быть не должно.

Хотя проблема в том, что указатели у Вас одинакового типа - это, скорее всего, не сработает.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

В 07.02.2023 в 12:19, Arlleex сказал:

А что насчет -fno-strict-aliasing в опциях компилятора? На уровнях O1 и выше отключится строгий алиасинг и оптимизирующего упреждающего чтения First вместе с Last быть не должно.

Хотя проблема в том, что указатели у Вас одинакового типа - это, скорее всего, не сработает.

Эта опция в данном случае помогла. С ней такой код нагенерило:

ER_IROM1:00002080                 LDR             R2, [R4,#8]
ER_IROM1:00002082                 MOVS            R1, #0
ER_IROM1:00002084                 STRH            R7, [R0,#8]
ER_IROM1:00002086                 STR             R6, [R0,#0xC]
ER_IROM1:00002088                 STRB            R1, [R0,#0x10]
ER_IROM1:0000208A                 STR             R1, [R0]
ER_IROM1:0000208C                 STR             R5, [R0,#4]
ER_IROM1:0000208E                 STR             R0, [R2]
ER_IROM1:00002090                 LDR             R2, [R4,#4]
ER_IROM1:00002092                 STR             R0, [R4,#8]
ER_IROM1:00002094                 CMP             R2, R0

Первая LDR -- это загрузка указателя Last, а последняя LDR -- это загрузка First; запись по адресу в Last, как видим, происходит непосредственно перед загрузкой First, поэтому всё будет корректно. Ну а без этой опции код такой:

ER_IROM1:00002006                 LDRD.W          R3, R1, [R4,#4]
ER_IROM1:0000200A                 MOVS            R2, #0
ER_IROM1:0000200C                 STRB            R2, [R0,#0x10]
ER_IROM1:0000200E                 STRD.W          R2, R8, [R0]
ER_IROM1:00002012                 STR             R0, [R1]
ER_IROM1:00002014                 ADDS            R1, R6, #1
ER_IROM1:00002016                 CMP             R3, R0
ER_IROM1:00002018                 STRH            R5, [R0,#8]
ER_IROM1:0000201A                 STR             R7, [R0,#0xC]
ER_IROM1:0000201C                 STR             R0, [R4,#8]
ER_IROM1:0000201E                 STRB.W          R1, [R4,#0x40]
ER_IROM1:00002022                 BNE             loc_207C

Переупорядочило, как видим, куда агрессивней -- и некорректно для этого случая. Ну а с volatile (и без опции) код такой:

ER_IROM1:00002022                 MOVS            R2, #0
ER_IROM1:00002024                 STR             R7, [R0,#4]
ER_IROM1:00002026                 STRH            R6, [R0,#8]
ER_IROM1:00002028                 STR.W           R8, [R0,#0xC]
ER_IROM1:0000202C                 STRB            R2, [R0,#0x10]
ER_IROM1:0000202E                 STR             R2, [R0]
ER_IROM1:00002030                 LDR             R1, [R4,#8]
ER_IROM1:00002032                 STR             R0, [R1]
ER_IROM1:00002034                 ADDS            R1, R5, #1
ER_IROM1:00002036                 STR             R0, [R4,#8]
ER_IROM1:00002038                 STRB.W          R1, [R4,#0x40]
ER_IROM1:0000203C                 LDR             R1, [R4,#4]
ER_IROM1:0000203E                 CMP             R1, R0
ER_IROM1:00002040                 BNE             loc_209C

 

А вот эта статейка навела меня на мысль, как сие исправить и без -fno-strict-aliasing, и без volatile: использовать объединение для поля First (одно поле -- указатель на сам заголовок, другое -- на первый элемент очереди). На досуге проверю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, SII сказал:
ER_IROM1:00002080                 LDR             R2, [R4,#8]
ER_IROM1:00002082                 MOVS            R1, #0
ER_IROM1:00002084                 STRH            R7, [R0,#8]
ER_IROM1:00002086                 STR             R6, [R0,#0xC]
ER_IROM1:00002088                 STRB            R1, [R0,#0x10]
ER_IROM1:0000208A                 STR             R1, [R0]
ER_IROM1:0000208C                 STR             R5, [R0,#4]
ER_IROM1:0000208E                 STR             R0, [R2]
ER_IROM1:00002090                 LDR             R2, [R4,#4]
ER_IROM1:00002092                 STR             R0, [R4,#8]
ER_IROM1:00002094                 CMP             R2, R0

Первая LDR -- это загрузка указателя Last, а последняя LDR -- это загрузка First; запись по адресу в Last, как видим, происходит непосредственно перед загрузкой First, поэтому всё будет корректно.

Странно, а мы видим иное: запись по адресу в Last, как видим, происходит непосредственно после загрузки First.  :unknw:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

28 минут назад, amaora сказал:

Так значит типы разные все таки бывают при работе с First и Last?

Видимо да:unknw: Тогда все достаточно законно компилятор нагенерировал, получается.

Я, так понял, здесь классическая "грабля" с оптимизацией при strict aliasing, которую каждая тематическая статья приводит в пример.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...