Как правильно установить константу в ассемблере gnu для семейства процессоров x86_64? - PullRequest
0 голосов
/ 01 марта 2020

Я учу себя ассемблеру 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 ассемблере.

...