Вы используете предварительные определения (без ненулевых инициализаторов), поэтому компилятор фактически не определяет расположение данных.Где-то в файле может быть определение (возможно, написанное на ассемблере), которое устанавливает совершенно другой порядок, чем тот, который компилятор создает в файле ассемблера, и тогда редактор ссылок будет вынужден размещать объекты в определенном порядке в секции вывода.
В моем случае Clang фактически производит это:
.type x,@object # @x
.comm x,4,4
.type y,@object # @y
.comm y,4,4
.type z,@object # @z
.comm z,4,4
.type w,@object # @w
.comm w,4,4
внешний ассемблер (из GNU binutils) превращает это в (как показано eu-readelf -s
;readelf -sW
должен работать одинаково хорошо):
18: 0000000000000004 4 OBJECT GLOBAL DEFAULT COMMON x
19: 0000000000000004 4 OBJECT GLOBAL DEFAULT COMMON y
20: 0000000000000004 4 OBJECT GLOBAL DEFAULT COMMON z
21: 0000000000000004 4 OBJECT GLOBAL DEFAULT COMMON w
(COMMON
из-за предварительного определения.)
внутренний ассемблер в самом Clang производит:
8: 0000000000000004 4 OBJECT GLOBAL DEFAULT COMMON w
9: 0000000000000004 4 OBJECT GLOBAL DEFAULT COMMON x
10: 0000000000000004 4 OBJECT GLOBAL DEFAULT COMMON y
11: 0000000000000004 4 OBJECT GLOBAL DEFAULT COMMON z
В моей системе BFD ld из binutils превращает это в:
54: 000000000060102c 4 OBJECT GLOBAL DEFAULT 23 z
55: 0000000000601030 4 OBJECT GLOBAL DEFAULT 23 x
65: 0000000000601034 4 OBJECT GLOBAL DEFAULT 23 w
66: 0000000000601038 4 OBJECT GLOBAL DEFAULT 23 y
Любопытно, что золото из той же версии binutils (2.28) производит:
25: 0000000000402014 4 OBJECT GLOBAL DEFAULT 24 w
26: 0000000000402020 4 OBJECT GLOBAL DEFAULT 24 z
27: 000000000040201c 4 OBJECT GLOBAL DEFAULT 24 y
28: 0000000000402018 4 OBJECT GLOBAL DEFAULT 24 x
Мое лучшее предположение заключается в том, что в случае BFD-ld это просто случайный порядок итераций в хэш-таблице, и золото использует лексикографический порядок символов.
Обратите внимание, что большая часть этого происходит из-за предварительных определений.и общие символы.Ассемблеру и редактору ссылок не разрешается переупорядочивать обычные определения объектов данных в одном и том же разделе, поэтому, если вы отключите использование общих символов, вы получите все, что компилятор произведет в выходных данных ассемблера.Порядок определения объекта все еще не определен языковым стандартом, но вы можете проверить руководство компилятора, если оно дает какие-либо дополнительные гарантии.