Я учу себя ассемблеру x86_64, и мои справочные тексты написаны на синтаксисе Intel, и я заинтересован в использовании синтаксиса AT & T с ассемблером gnu и выяснил большую часть различий, но я не могу понять, как правильно установить константы сродни ключевому слову #define препроцессора C.
Например, давайте возьмем такой простой пример helloworld:
.globl _start
_start:
movq $1, %rax
movq $1, %rdi
movq $MESG, %rsi
movq $13, %rdx
syscall
movq $60, %rax
movq $0, %rdi
syscall
После сборки вывод nm
для исполняемого файла :
0000000000000000 d MESG
0000000000000000 T _start
Два хороших символа, однако, что будет дальше:
.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
Вывод nm
для этого исполняемого файла показывает новые символы в разделе данных
000000000000001c d FILENO_STDOUT
0000000000000000 d MESG
0000000000000000 T _start
0000000000000014 d SYS_exit
000000000000000c d SYS_write
Однако это не только данные для чтения, которые есть у константы, но это только начало.
Моя следующая мысль состояла в том, чтобы просто вставить мои метки в раздел .rodata
.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
Это был nm
результат:
000000000000001c r FILENO_STDOUT
0000000000000000 r MESG
0000000000000000 T _start
0000000000000014 r SYS_exit
000000000000000c r SYS_write
Что, кажется, то, что я хочу, однако я заметил в руководстве по газу, что есть директива ассемблера .set / .equ, которая, кажется, делает тот же
.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
Однако вывод nm
ниже показывает, что символ представляет собой строчную букву «а», которая, как я полагаю, является просто другой формой «А», описанной в руководстве по нм для описания абсолютного символы. Также я заметил, что в программе произошел сбой, если я не поставил непосредственный сигнал для метки, определенной с помощью директивы set.
0000000000000001 a FILENO_STDOUT
0000000000000000 d MESG
0000000000000000 T _start
0000000000000014 d SYS_exit
000000000000000c d SYS_write
Все это говорит о том, что, если что-либо из перечисленного выше, является правильным способом определения констант в GNU ассемблере.