В настоящее время я изучаю сборку с помощью ассемблера NASM, и я застрял в разнице между section и label. Я понял, что section .dat
, .bss
или .text
используются в качестве стандарта для объявления или инициализации переменных и в качестве ловушки компоновщика, такой как main()
в C. Но также метки используются для назначения раздела в коде. Так что же скрывается за неясной правдой?
В чем разница между разделом и меткой в сборке в NASM?
Ответы (1)
Знаете, есть неплохой мануал. http://www.nasm.us, если у вас его нет.
Имеет значение, какой формат вывода вы используете — переключатель -f
. В общем... section
и segment
это псевдонимы, они делают одно и то же. Они не чувствительны к регистру, вы можете использовать SEGMENT
, если хотите. Большинство выходных форматов (не -f obj
) имеют "известные имена" - .text
, .data
, .bss
(и еще несколько). Они чувствительны к регистру — section .TEXT
может не делать то, что вы хотите. Обычно section .text
является исполняемым, но доступным только для чтения. Попытка записи в него вызовет ошибку сегментации (или как там Windows это называет — GPF?). section .data
для ваших инициализированных данных - msg db "Hello World!", 0
или frooble_count dd 42
. section .bss
предназначен для неинициализированных данных, он только резервирует место в памяти и не включается в файл на диске. Там можно использовать только "резервные" псевдоинструкции - resb
, resw
, resd
и т.д. Параметр после него указывает, сколько байт (и т.д.) вы хотите зарезервировать. В выходном формате -f bin
нет разделов/сегментов (это то, что делает его «плоским бинарным») — Nasm просто делает .text
первым, перемещает .data
после него и .bss
последним — вы можете записывать их в любом порядке.
Ярлыки НЕ определяют раздел! Nasm просто переводит их в числа — адреса, по которым они встречаются в вашем коде — и вот что появляется в вашем исполняемом файле. Вы можете использовать метку как имя переменной или как точку в своем коде, к которой вы можете захотеть call
или jmp
. Все равно к Nasm. Некоторые ассемблеры «запоминают» указанный вами размер переменной и выдают ошибку, если вы попытаетесь использовать ее неправильно. У Насма амнезия - можно mov [mybyte], eax
терпеть без жалоб. Иногда это полезно, чаще это ошибка. «Слишком большая» переменная, как правило, не является проблемой — «слишком маленькая» переменная может вызвать ошибку, которая часто проявляется позже. Трудно отлаживать! Метка не может начинаться с десятичной цифры (и число должно начинаться с десятичной цифры). Метка, которая начинается с точки (точки), является локальной меткой. Его область действия — от последней нелокальной метки до следующей нелокальной метки. Подробности см. в Дружественном руководстве — это только введение.
Слово «основной» не означает ничего особенного для Nasm, но известно C (если вы линкуете против C). Некоторые компиляторы пишут его как main
, некоторые _main
, некоторые (OpenWatcom) даже пишут его как main_
. Это точка входа, где начинается выполнение, когда управление передается вашей программе. Он не обязательно должен быть первым в section .text
, но должен быть в этом разделе и должен быть объявлен "глобальным", чтобы сообщить об этом компоновщику. «_start» — это точка входа по умолчанию для Linux (и т. д.). В отличии от "main" он не call
ed, так что ret
из него нельзя. Можно использовать другое имя, но вам нужно сообщить об этом ld (-e myentry
). Это тоже должно быть global
.
Пока достаточно. См. руководство и возвращайтесь, если (ха!) у вас есть другие вопросы.
bss
не является неинициализированным как таковым. Он неявно инициализируется нулями, потому что все страницы, которые ОС выделяет программе, обнуляются, чтобы одна программа не могла читать старые данные другой.
- person EOF; 22.11.2014
start=
, vstart=
, follows=
, vfollows=
, align=
и valign=
.
- person ecm; 03.12.2020
.text
для исполняемого кода или.rodata
для данных только для чтения (константы). метка — это адрес памяти, определяющий переменную в памяти или начало расширенного базового блока кода. - person EOF   schedule 22.11.2014