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.

1

As 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:

  • .word is simple: it outputs 2 bytes to the object file no matter where we are.

    Consequences of this:

    • if .word is after a symbol x:, x will point to those bytes
    • if .word is in the text segment, those bytes might get executed

    It has absolutely no other side effect. In particular, it does not set the st_size field of the symbol table entry (e.g. int often == 4 bytes), which is something sensible compilers should do. You need the .size x, 2 directive for that.

  • .equ does two things:

    1. updates a macro-like variable
    2. the last time you call it, it generates a symbol with st_shndx == SHN_ABS and 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.o 

    Gives:

    00000000 <.text>: 0: b8 7b 00 00 00 mov $0x7b,%eax 5: b8 c8 01 00 00 mov $0x1c8,%eax 

    which confirms the macro-like effect, and:

    readelf -s main.o 

    contains:

    Num: Value Size Type Bind Vis Ndx Name 4: 000001c8 0 NOTYPE LOCAL DEFAULT ABS x 

    which confirms the SHN_ABS effect: 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 at

    The situation is analogous for NASM's equ, except that the NASM version can only be used once per symbol.

    .set and the equals sign = (source) are the same as .equ.

    You should also look into .equiv , which prevents redefinition.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy