0

I am teaching myself x86_64 assembly and my reference texts are in intel syntax and I am interested in using AT&T syntax with the gnu assembler and have figured out most of the difference but I cant figure out what is the proper way to set constants akin to the #define keyword of the C pre-processor.

For example lets take this simple helloworld example:

.globl _start
_start:
        movq $1, %rax
        movq $1, %rdi
        movq $MESG, %rsi
        movq $13, %rdx
        syscall

        movq $60, %rax
        movq $0, %rdi
        syscall

Once assembled the nm output for the executable is:

0000000000000000 d MESG
0000000000000000 T _start

Two symbols so far so good however what comes next is.

.globl _start
_start:
        movq SYS_write, %rax
        movq FILENO_STDOUT, %rdi
        movq $MESG, %rsi
        movq $13, %rdx
        syscall

        movq SYS_exit, %rax
        movq $0, %rdi
        syscall

.data
MESG:          .ascii "Hello World\n"
SYS_write:     .quad  1
SYS_exit:      .quad  60
FILENO_STDOUT: .quad 1

The nm output for this executable shows new symbols in the data section

000000000000001c d FILENO_STDOUT
0000000000000000 d MESG
0000000000000000 T _start
0000000000000014 d SYS_exit
000000000000000c d SYS_write

However this isnt readonly data that a constant would have but it is a start.

My next thought was just to stick my labels into the .rodata section

.globl _start
_start:
        movq SYS_write, %rax
        movq FILENO_STDOUT, %rdi
        movq $MESG, %rsi
        movq $13, %rdx
        syscall

        movq SYS_exit, %rax
        movq $0, %rdi
        syscall

.data

.section .rodata
MESG:          .ascii "Hello World\n"
SYS_write:     .quad  1
SYS_exit:      .quad  60
FILENO_STDOUT: .quad 1

This was the nm result:

000000000000001c r FILENO_STDOUT
0000000000000000 r MESG
0000000000000000 T _start
0000000000000014 r SYS_exit
000000000000000c r SYS_write

Which seems to be what I want however I noticed in the gas manual that there is an assembler directive .set / .equ which seems to do the same

.globl _start
_start:
        movq SYS_write, %rax
        movq $FILENO_STDOUT, %rdi
        movq $MESG, %rsi
        movq $13, %rdx
        syscall

        movq SYS_exit, %rax
        movq $0, %rdi
        syscall

.data
MESG:        .ascii "Hello World\n"
SYS_write:   .quad  1
SYS_exit:    .quad  60
#FILENO_STDOUT: .quad 1
.set    FILENO_STDOUT, 1

However the nm output below shows that the symbol is a lower case 'a' which I am assuming is just another form of the 'A' described in the nm manual to describe absolute symbols. Also I noticed that the program segfaulted if I did not put the immediate sigal for the label defined with the set directive.

0000000000000001 a FILENO_STDOUT
0000000000000000 d MESG
0000000000000000 T _start
0000000000000014 d SYS_exit
000000000000000c d SYS_write

All that being said which if any of the above is the proper way to define constants in gnu assembler.

Zeno of Elea
  • 175
  • 11
  • 1
    See [`.set` in the gas manual](https://sourceware.org/binutils/docs/as/Set.html) And yeah, you will need the `$` for an immediate. – Jester Mar 01 '20 at 01:51
  • 1
    `.equ` is the usual way to define assemble-time constants; in other assemblers EQU constants are even more different from symbols defined by labels than they are in GAS. BTW, `#include ` to get the right defines so you can just use `mov $__NR_write, %eax` instead of defining it yourself, let alone loading it from memory). (Name your source file foo.S so `gcc` will run it through CPP before assembling. `gcc -nostdlib -static hello.S`). Also, see [How to load address of function or label into register in GNU Assembler](//stackoverflow.com/q/57212012) - use RIP-relative! – Peter Cordes Mar 01 '20 at 02:01
  • So if I am understand this correctly .equ & .set are assemble-time constants like a C preprocessor #define (basically a mnemonic label for an immediate value) while .byte /.long /.int /.quad/ etc are directives to allocate memory and give it a value? Also thanks for the tip I hadn't thought just using the c pre processor. – Zeno of Elea Mar 03 '20 at 15:27

0 Answers0