pmg ответ будет работать только в том случае, если первые 9 бит уже равны нулю.Если были установлены какие-то биты, ваши данные получат ORed вместе с ними.Итак, чтобы убедиться, что вам нужно сначала очистить эти биты:
#define POS 23 // position at which to insert data
#define MASK ((1UL<<9)-1) // mask of nine 1s
word = (word & ~(MASK<<POS)) | ((data9 & MASK) << POS));
Первая часть сместит маску в целевую позицию, а затем инвертирует ее, так что вы получите нули в целевых старших битах идля остальной части слова, поэтому операция AND удалит первые 9 бит и оставит младшие биты без изменений.Вторая часть убедится, что у нас установлено только 9 битов, а затем сместит их в целевую позицию.Наконец, две части будут объединены с операциями ИЛИ, и из-за маскировки они не будут мешать.