Мне любопытно - В чем разница между .equ
и .word
директивами в сборке ARM при определении констант?Разница между .equ и .word в ARM Assembly?
ответ
.word - это директива, которая выделяет размер пространства для хранения (памяти) размером в слово в этом месте. Он может дополнительно иметь такое местоположение, инициализированное заданным значением.
.equ больше похож на инструкцию для препроцессора C#define - он заменяется в любом последующем коде.
https://sourceware.org/binutils/docs-2.24/as/Equ.html#Equ
https://sourceware.org/binutils/docs-2.24/as/Word.html#Word
Это на самом деле не ARM конкретных, но относится ко всем целям газа.
.equ
подобен #define
в C:
#define bob 10
.equ bob, 10
.word
подобен unsigned int
в C:
unsigned int ted;
ted:
.word 0
Или инициализируется со значением:
unsigned int alice = 42;
alice:
.word 42
, и это не имеет ничего общего с ARM, это верно для большинства/всех платформ, поддерживаемых ассемблером gnu и другими ассемблерами с этими директивами. –
Это работает - +1 для операторов C. Спасибо! – jhtong
Nitpicking :-) 1) '.word как unsigned int в C': но он не устанавливает' st_size' как большинство компиляторов C, и его можно использовать в любом месте, например. в текстовом разделе для генерации кода. 2) '.equ как # define': но он также генерирует символ ABS || Более подробная информация: http://stackoverflow.com/a/33157659/895245 –
NASM выход 2.10.09 ELF:
.word
проста: она выводит 2 байта в файле объекта, независимо от того, где мы находимся.Последствие этого:
- если
.word
после символаx:
,x
будет указывать на эти байты - если
.word
находится в текстовом сегменте, эти байты могут получить выполненные
У этого нет абсолютно никакого побочного эффекта. В частности, не устанавливает поле
st_size
записи таблицы символов (например,int
часто == 4 байта), что и должно делать разумные компиляторы. Для этого вам нужна директива.size x, 2
.- если
.equ
делает две вещи:- обновляет макро-как переменная
- последний раз, когда вы называете его, он генерирует символ с
st_shndx == SHN_ABS
и заданное значение
Пример кода:
.text .equ x, 123 mov $x, %eax /* eax == 123 */ .equ x, 456 mov $x, %eax /* eax == 456 */
Сейчас:
as --32 -o main.o main.S objdump -Sr main.o
Дает:
00000000 <.text>: 0: b8 7b 00 00 00 mov $0x7b,%eax 5: b8 c8 01 00 00 mov $0x1c8,%eax
, который подтверждает макро-подобный эффект, а также:
readelf -s main.o
содержит:
, который подтверждает Эффект
SHN_ABS
: был создан символ, и его можно было использовать из другого файла путем ссылки, если он был глобальным. Я объяснил это более подробно на https://stackoverflow.com/a/33148242/895245Аналогичная ситуация для NASM
equ
, за исключением того, что версия NASM может использоваться только один раз на символ..set
и знак равенства=
(source) - это то же самое, что и.equ
.Вы также должны изучить
.equiv
https://sourceware.org/binutils/docs-2.25/as/Equiv.html, что предотвращает переопределение.
Я просто хотел уточнить, что вы не можете использовать '.word' для инициализации переменных в ОЗУ ... вам нужно что-то во время выполнения, чтобы это сделать. –