Почему я не могу получить длину своей строки с помощью метода вычитания?
Я пишу небольшую программу сборки, чтобы распечатать строку, которую я могу объявить в section .data
раздел. Я использую ассемблер NASM x64 на 64-битной macOS.
Я знаю, что для вывода чего-либо на экран мне нужно syscall
то write
подпрограмма, которой требуется, чтобы длина строки была напечатана в качестве третьего параметра. Чтобы определить длину строки, я решил, что могу использовать один регистр для индексации строки (rax
в приведенном ниже коде), а другой действует как счетчик (rdx
в коде ниже). Я буду увеличивать их оба, пока текущий байт не равен нулю. Для краткости я опустил код.
Это работает, но потом я подумал, что мог бы сделать этот код быстрее, только увеличивая rax
, и когда я дойду до конца строки, вычисляю (rax - msg), чтобы узнать, сколько раз я увеличил rax
. Кроме того, зачем мне делать это вrax
, когда я мог делать все в rdx
, где третий аргумент к write
пойдет? Это спасет другогоmov
инструкция! Так я и сделал:
global start
section .text
start:
mov rdx, msg
nextchar:
cmp byte[rdx], 0
jz done
inc rdx
jmp nextchar
done:
sub rdx, msg ; <------ here I do the calculation I mentioned
mov rax, 0x2000004 ; write
mov rdi, 1 ; stdout
mov rsi, msg
syscall
mov rax, 0x2000001 ; exit
mov rdi, 0
syscall
section .data
msg: db "hello", 10 ; <---- I want to print this string
Но когда я собираюсь с nasm -f macho64 code.asm
, Я получил ошибку в sub
инструкция:
64-битный формат Mach-O не поддерживает 32-битные абсолютные адреса
Я погуглил сообщение об ошибке и нашел его, но, похоже, это не связано со строками илиsub
инструкция. Этот пост, похоже, посвящен помещению данных в стек.
я догадываюсь msg
это "32-битный абсолютный адрес", о котором идет речь в ошибке, но почему он 32-битный? И как я могу найти длину строки с помощью этого метода вычитания?