I am curious - What is the difference between .equ and .word directives in ARM assembly, when defining constants?
4 Answers
.equ is like #define in C:
#define bob 10 .equ bob, 10 .word is like unsigned int in C:
unsigned int ted; ted: .word 0 Or initialized with a value:
unsigned int alice = 42; alice: .word 42 5.word is a directive that allocates a word-sized amount of storage space (memory) in that location. It can additionally have that location initialized with a given value.
.equ is more like a C preprocessor #define statement - it gets substituted in any subsequent code.
This is not actually ARM-specific, but applies to all gas targets.
1As mentioned in the accepted answer (written by old_timer) label: .word value is like assigning a value to that label. I just want to add that you can assign multiple values to the same label just like an array, as the following:
g_pfnVectors: .word _estack .word Reset_Handler .word NMI_Handler .word HardFault_Handler .word MemManage_Handler ... The previous example has been taken from a STM32 MCU official startup file. This is exactly the machanism to initialize the NVIC.
So g_pfnVectors label got multiple values assigned (as an array, where the values are aligned next to each other in the memory so to say).
NASM 2.10.09 ELF output:
.wordis simple: it outputs 2 bytes to the object file no matter where we are.Consequences of this:
- if
.wordis after a symbolx:,xwill point to those bytes - if
.wordis in the text segment, those bytes might get executed
It has absolutely no other side effect. In particular, it does not set the
st_sizefield of the symbol table entry (e.g.intoften == 4 bytes), which is something sensible compilers should do. You need the.size x, 2directive for that.- if
.equdoes two things:- updates a macro-like variable
- the last time you call it, it generates a symbol with
st_shndx == SHN_ABSand the given value
Sample code:
.text .equ x, 123 mov $x, %eax /* eax == 123 */ .equ x, 456 mov $x, %eax /* eax == 456 */Now:
as --32 -o main.o main.S objdump -Sr main.oGives:
00000000 <.text>: 0: b8 7b 00 00 00 mov $0x7b,%eax 5: b8 c8 01 00 00 mov $0x1c8,%eaxwhich confirms the macro-like effect, and:
readelf -s main.ocontains:
Num: Value Size Type Bind Vis Ndx Name 4: 000001c8 0 NOTYPE LOCAL DEFAULT ABS xwhich confirms the
SHN_ABSeffect: a symbol was created, and it could be used from another file by linking if it were global. I have explained this in more detail atThe situation is analogous for NASM's
equ, except that the NASM version can only be used once per symbol..setand the equals sign=(source) are the same as.equ.You should also look into
.equiv, which prevents redefinition.