В чем разница между разделом и меткой в ​​сборке в NASM?

В настоящее время я изучаю сборку с помощью ассемблера NASM, и я застрял в разнице между section и label. Я понял, что section .dat, .bss или .text используются в качестве стандарта для объявления или инициализации переменных и в качестве ловушки компоновщика, такой как main() в C. Но также метки используются для назначения раздела в коде. Так что же скрывается за неясной правдой?


person ovrwngtvity    schedule 21.11.2014    source источник
comment
Раздел — это область памяти, связанная с определенной целью, например. .text для исполняемого кода или .rodata для данных только для чтения (константы). метка — это адрес памяти, определяющий переменную в памяти или начало расширенного базового блока кода.   -  person EOF    schedule 22.11.2014
comment
Итак, если я понял, раздел - это заранее определенная область памяти, связанная с определенной целью?   -  person ovrwngtvity    schedule 22.11.2014


Ответы (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" он не called, так что ret из него нельзя. Можно использовать другое имя, но вам нужно сообщить об этом ld (-e myentry). Это тоже должно быть global.

Пока достаточно. См. руководство и возвращайтесь, если (ха!) у вас есть другие вопросы.

person Frank Kotler    schedule 22.11.2014
comment
Почти уверен, что bss не является неинициализированным как таковым. Он неявно инициализируется нулями, потому что все страницы, которые ОС выделяет программе, обнуляются, чтобы одна программа не могла читать старые данные другой. - person EOF; 22.11.2014
comment
Верно. В файле .com для DOS, где на самом деле нет разделов, вы можете установить значение в .bss, завершить программу и запустить ее снова, не загрузив ничего другого, и найти свое значение все еще там. Так что в этом случае .bss действительно не инициализирован. DOS не слишком хорош с безопасностью. Во всех (?) других случаях .bss заполняется ОС нулями. Я не уверен, что мы должны рассчитывать на это, но это правда. Я пытался сделать это просто. Может быть, слишком просто. Спасибо за исправление! - person Frank Kotler; 22.11.2014
comment
Формат NASM поддерживает несколько разделов с разными именами, параметрами start=, vstart=, follows=, vfollows=, align= и valign=. - person ecm; 03.12.2020