file_name equ "a.txt"
определяет file_name
только для времени сборки числовая константа 1 . Неважно, в каком разделе эта директива появляется; он не собирает байтов в вывод. equ
это просто вещь, постоянная во времени сборки. Аналогично %define
строковой подстановке, но оно вычисляет выражение до числа на месте. (Это имеет значение для выражения, включающего $
, например msglen equ $ - msg
.)
Но вам нужна ваша строка в памяти, и для передачи системного вызова указатель на C-строку (неявная длина) с нулем в конце . Интерфейс системного вызова принимает только указатели, а не значения; в противном случае он не сможет обрабатывать имена файлов длиннее 8 байт. (Или 4 байта в 32-битных системах).
Таким образом
default rel
section .rodata ; read-only data doesn't need to be in read-write .data
file_name: db "a.txt", 0 ; the 0 terminator is important, this is a C string.
section .text
...
lea rdi, [file_name] ;or mov rsi, file_name for the inefficient way
Стандартный способ помещения статических адресов в регистры в x86-64 - это LEA, относящийся к RIP. (default rel
). mov edi, symbol
работает в исполняемых файлах, отличных от PIE, но в принципе никогда не имеет смысла использовать mov rdi, symbol
(10-байтовый mov r64, imm64
).
Сноска 1:
NASM допускает многосимвольные константы в любом контексте, где допускается числовой литерал. например mov rax, 'a.txt'
в точности эквивалентно mov rax, 0x7478742e61
, поэтому mov [mem], rax
поместит строку в память (потому что x86 имеет младший порядок), за которым следуют 3 байта нулей.
file_name equ "a.txt"
в точности эквивалентно file_name equ 0x7478742e61