Как проверить адрес памяти, 32 бита выровнены в C

Мой вопрос состоит из двух частей.

Во-первых, как новичок в этом адресном пространстве, я хотел бы знать, в чем смысл выравнивания памяти адреса. Я разобрался в этом, но хотел задать этот вопрос здесь, так как нашел ответы здесь очень полезными.

Вторая часть моего вопроса связана с выравниванием и программированием: как найти, соответствует ли адрес 4 байтам или нет? Где-то я читал:

  if(address & 0x3) // for 32 bit register 

Но я действительно не знаю, как это проверяет выравнивание по 4 байт. Может ли кто-нибудь объяснить это подробно?

Редактировать: Было бы здорово, если кто-то сможет нарисовать живописный вид на эту тему.

Спасибо

Ответ 1

Последовательные адреса относятся к последовательным байтам в памяти.

Адрес, который выровнен по 4 байтам, является кратным 4 байтам. Другими словами, двоичное представление адреса заканчивается двумя нулями (00), так как в двоичном выражении оно кратно двоичному значению 4 (100b). Тест для 4-байтового выровненного адреса, следовательно:

if ( (address & 0x3) == 0 )
{
    // The address is 4-byte aligned here
}

или просто

if ( !(address & 0x3) )
{
    // The address is 4-byte aligned here
}

0x3 является двоичным 11 или маской младших двух битов адреса.

Выравнивание важно, поскольку некоторые операции ЦП быстрее, если адрес элемента данных выровнен. Это связано с тем, что процессоры основаны на 32-битных или 64-битных словарях. Небольшие объемы данных (например, 4 байта, например) идеально подходят для 32-битного слова, если оно выровнено по 4 байт. Если он не выровнен, он может пересекать 32-разрядную границу и требует дополнительных выборок памяти. У современных процессоров есть и другие оптимизации, которые повышают производительность для выровненных по адресам данных.

Вот пример статьи по теме выравнивания и скорости.

Вот несколько хороших диаграмм выравнивания.