Как правило, единственный надежный способ убедиться, что определенная последовательность инструкций выполняется последовательно, - записать их все в одном выражении asm volatile
.
Руководство * g cc говорит об этом в явном виде (6.47.2.2):
Не ожидайте, что последовательность ассемблерных операторов останется идеально последовательной после компиляции, даже если вы используете volatile квалификатор. Если определенные инструкции должны оставаться последовательными в выходных данных, поместите их в один оператор asm из нескольких инструкций.
Я не уверен, какую архитектуру вы имеете в виду, но для вашего второго примера, в частности, компилятору может потребоваться выполнить некоторую работу перед каждым writel
, чтобы получить соответствующий адрес в соответствующем регистр. Чтобы удовлетворить ваши требования, вы бы хотели, чтобы он выполнил всю эту работу заранее, и я не знаю ни одного способа заставить это сделать это.
Обычно указание компилятору «не оптимизировать» Совершенная sh противоположность того, что вы хотите. Например, в вашем первом примере без оптимизации компилятор, вероятно, не поймет, что он может хранить addr
в одном и том же регистре, и будет генерировать код для его перезагрузки каждый раз.