Описание файла, который подключается к программе на ассемблере
Обновлено: 21.11.2024
Дескриптор файла – это 16-битное целое число, присвоенное файлу в качестве идентификатора файла. Когда создается новый файл или открывается существующий файл, дескриптор файла используется для доступа к файлу.
Файловый дескриптор стандартных файловых потоков — stdin, stdout и stderr равен 0, 1 и 2 соответственно.
Указатель файла
Указатель файла указывает место для последующей операции чтения/записи в файле в байтах. Каждый файл рассматривается как последовательность байтов. Каждый открытый файл связан с указателем файла, который определяет смещение в байтах относительно начала файла. Когда файл открывается, указатель файла устанавливается на ноль.
Файловая обработка системных вызовов
В следующей таблице кратко описаны системные вызовы, связанные с обработкой файлов.
%eax | Имя | %ebx | %ecx | %edx |
---|---|---|---|---|
2 | sys_fork | struct pt_regs | -< /td> | - |
3 | sys_read | unsigned int | char * td> | size_t |
4 | sys_write | unsigned int | const char * td> | size_t |
5 | sys_open | const char * | int | int |
6 | sys_close | unsigned int | - | < td>-|
8 | sys_creat | const char * | int | - |
19 | sys_lseek | unsigned int | off_t | unsigned int |
Шаги, необходимые для использования системных вызовов, такие же, как мы обсуждали ранее —
- Поместите номер системного вызова в регистр EAX.
- Сохраняйте аргументы системного вызова в регистрах EBX, ECX и т. д.
- Вызов соответствующего прерывания (80h).
- Результат обычно возвращается в регистр EAX.
Создание и открытие файла
Для создания и открытия файла выполните следующие задачи —
- Поместите системный вызов sys_creat() под номером 8 в регистр EAX.
- Поместите имя файла в регистр EBX.
- Поместите права доступа к файлам в регистр ECX.
Системный вызов возвращает файловый дескриптор созданного файла в регистре EAX, в случае ошибки код ошибки находится в регистре EAX.
Открытие существующего файла
Чтобы открыть существующий файл, выполните следующие задачи —
- Поместите системный вызов sys_open() под номером 5 в регистр EAX.
- Поместите имя файла в регистр EBX.
- Поместите режим доступа к файлу в регистр ECX.
- Поместите права доступа к файлам в регистр EDX.
Системный вызов возвращает файловый дескриптор созданного файла в регистре EAX, в случае ошибки код ошибки находится в регистре EAX.
Чтение из файла
Для чтения из файла выполните следующие задачи —
Поместите системный вызов sys_read() номер 3 в регистр EAX.
Поместите файловый дескриптор в регистр EBX.
Поместите указатель на входной буфер в регистр ECX.
Поместите размер буфера, т. е. количество байтов для чтения, в регистр EDX.
Системный вызов возвращает количество прочитанных байтов в регистре EAX, в случае ошибки код ошибки находится в регистре EAX.
Запись в файл
Для записи в файл выполните следующие задачи —
Поместите системный вызов sys_write() номер 4 в регистр EAX.
Поместите файловый дескриптор в регистр EBX.
Поместите указатель на выходной буфер в регистр ECX.
Поместите размер буфера, т. е. количество байтов для записи, в регистр EDX.
Системный вызов возвращает фактическое количество байтов, записанных в регистр EAX, в случае ошибки код ошибки находится в регистре EAX.
Закрытие файла
Чтобы закрыть файл, выполните следующие задачи —
- Поместите системный вызов sys_close() под номером 6 в регистр EAX.
- Поместите файловый дескриптор в регистр EBX.
В случае ошибки системный вызов возвращает код ошибки в регистре EAX.
Обновление файла
Для обновления файла выполните следующие задачи —
- Поместите системный вызов sys_lseek() под номером 19 в регистр EAX.
- Поместите файловый дескриптор в регистр EBX.
- Поместите значение смещения в регистр ECX.
- Поместите опорную позицию для смещения в регистр EDX.
Исходная позиция может быть:
- Начало файла — значение 0
- Текущая позиция – значение 1
- Конец файла — значение 2
В случае ошибки системный вызов возвращает код ошибки в регистре EAX.
Пример
Следующая программа создает и открывает файл с именем myfile.txt и записывает в этот файл текст «Добро пожаловать в Tutorials Point». Затем программа читает из файла и сохраняет данные в буфер с именем info. Наконец, он отображает текст, хранящийся в info.
Когда приведенный выше код скомпилирован и выполнен, он дает следующий результат —
В чем разница между объектным кодом, машинным кодом и ассемблерным кодом?
Можете ли вы привести наглядный пример их различия?
Мне также интересно, откуда взялось название "код объекта"? Что означает в нем слово «объект»? Это как-то связано с объектно-ориентированным программированием или просто совпадение имен?
Я не спрашиваю о том, что такое объектный код, Капитан Очевидность. Я спрашиваю о том, откуда произошло название и почему он называется "объектным" кодом.
10 ответов 10
Машинный код — это двоичный код (1 и 0), который может выполняться непосредственно ЦП. Если вы откроете файл с машинным кодом в текстовом редакторе, вы увидите мусор, в том числе непечатаемые символы (нет, не эти непечатаемые символы ;)).
Объектный код — это часть машинного кода, еще не объединенная в полную программу. Это машинный код для одной конкретной библиотеки или модуля, из которых состоит готовый продукт. Он также может содержать заполнители или смещения, которых нет в машинном коде завершенной программы. Компоновщик будет использовать эти заполнители и смещения, чтобы соединить все вместе.
Код на ассемблере представляет собой простой текст и (в некоторой степени) удобочитаемый исходный код, который в основном имеет прямой аналог 1:1 с машинными инструкциями. Это достигается с помощью мнемоники для реальных инструкций, регистров или других ресурсов. Примеры включают JMP и MULT для инструкций ЦП по переходу и умножению. В отличие от машинного кода, процессор не понимает ассемблерный код. Вы конвертируете ассемблерный код в машинный код с помощью ассемблера или компилятора, хотя мы обычно думаем о компиляторах в связи с языком программирования высокого уровня, который более абстрагирован от инструкций процессора.
Создание законченной программы включает в себя написание исходного кода программы либо на ассемблере, либо на языке более высокого уровня, таком как C++. Исходный код собирается (для ассемблерного кода) или компилируется (для языков более высокого уровня) в объектный код, а отдельные модули связываются вместе, чтобы стать машинным кодом для конечной программы. В случае очень простых программ этап компоновки может не понадобиться. В других случаях, например в IDE (интегрированная среда разработки), компоновщик и компилятор могут вызываться вместе. В других случаях можно использовать сложный скрипт make или файл решения, чтобы сообщить среде, как собрать окончательное приложение.
Есть также интерпретируемые языки, которые ведут себя иначе. Интерпретируемые языки полагаются на машинный код специальной программы-интерпретатора. На базовом уровне интерпретатор анализирует исходный код, немедленно преобразует команды в новый машинный код и выполняет их. Современные интерпретаторы теперь намного сложнее: они одновременно оценивают целые разделы исходного кода, кэшируют и оптимизируют, где это возможно, и выполняют сложные задачи управления памятью.
Последний тип программы предполагает использование среды выполнения или виртуальной машины. В этой ситуации программа сначала предварительно компилируется в промежуточный язык более низкого уровня или в байт-код. Затем байт-код загружается виртуальной машиной, которая вовремя компилирует его в собственный код. Преимущество здесь в том, что виртуальная машина может использовать преимущества оптимизации, доступные во время запуска программы и для этой конкретной среды. Компилятор принадлежит разработчику и, следовательно, должен создавать относительно общий (менее оптимизированный) машинный код, который может выполняться во многих местах. Однако среда выполнения или виртуальная машина находятся на компьютере конечного пользователя и поэтому могут использовать все функции, предоставляемые этой системой.
Создать программу для микроконтроллера немного сложнее, чем создать программу для ПК. Когда вы создаете программу для ПК, вы разрабатываете ее с использованием того же типа компьютерной системы, на которой программа будет работать. Итак, вы пишете свой программный код, компилируете его, а затем запускаете программу на своем ПК или аналогичном ПК. Дело в том, что хост-система (где выполняется разработка) такая же, как и целевая система (где программа будет работать). Хост в некотором смысле «знает» все о целевой системе, поскольку они одинаковы.
Когда вы создаете программу для микроконтроллера, вы создаете программу, используя одну систему (хост-компьютер), которая будет работать на совершенно другой целевой системе (HCS12); это известно как «перекрестное развитие». ПК ничего не знает о целевой системе, для которой мы разрабатываем. Вы должны сказать ему, как преобразовать исходный код в машинный код, где разместить машинный код в памяти целевой системы, как загрузить программу с ПК в целевую систему и т. д. Ниже приведены шаги, описывающие процедуру сделай это. Дополнительные сведения можно найти в глоссарии, если некоторые термины вам незнакомы.
Конечная программа, которая запускается на целевом компьютере HCS12, называется исполняемой программой или просто «исполняемой программой». Шаги по созданию исполняемой программы для HCS12 кратко описаны ниже. Система разработки, которую мы используем для создания исполняемого файла, представляет собой полностью интегрированную среду под названием «Code Warrior» от Metrowerks (мы используем Code Warrior Special Edition для HCS12, v.3). Обсуждение ниже относится конкретно к Code Warrior, но другие системы разработки работают аналогичным образом.
<р>1. Сначала вы создаете программу сборки с помощью текстового редактора, такого как встроенный редактор Code Warrior. Программа на ассемблере, которую вы пишете, представляет собой текстовый файл, состоящий из операторов языка ассемблера, директив и т. д. Расширение файла программы на ассемблере — «.asm» для ассемблера Code Warrior, но часто «.s» для других ассемблеров. Код сборки называется исходным кодом, а файл программы сборки обычно называется исходным файлом. <р>2. Затем программа сборки запускается через программу, называемую ассемблером, которая преобразует исходный код в двоичную форму, подходящую для HCS12. Ассемблер построчно преобразует операторы языка ассемблера в машинный код и генерирует объектный файл с расширением .o, который содержит то, что люди называют объектным кодом. Объектный файл имеет формат, называемый форматом ELF/DWARF (см. глоссарий ), и в дополнение к машинному коду содержит определенный объем служебных данных.> Обратите внимание, что используемая нами программа на ассемблере находится на «хост-компьютере» (вашем ПК), но создает программу для другого типа компьютера, называемого «целевым» (здесь HCS12), поэтому используемый нами ассемблер часто называют "кросс-ассемблером".
<р>3. Объектный файл .o, созданный ассемблером, является промежуточным файлом, который содержит необходимый машинный язык HCS12, но его все же необходимо несколько изменить. Например, может потребоваться объединить или связать его с другими файлами объектного кода, такими как библиотечные подпрограммы, чтобы создать окончательную программу, которая будет фактически работать на микроконтроллере. Ему также может потребоваться разрешить адреса, которые неизвестны, пока с ним не будут связаны другие файлы.Задачей компоновщика является создание полного файла машинного кода, который (почти) готов к запуску на HCS12. Компоновщик делает это, заполняя неразрешенные адреса и связывая связанные программы для создания окончательной программы. Файл, созданный компоновщиком, называется абсолютным файлом и имеет расширение .abs. Абсолютный файл содержит исполняемый машинный код, который будет использоваться HCS12, а также служебную информацию, такую как назначения адресов для кода и т. д. Файл .abs, который мы генерируем с помощью компоновщика, иногда называют исполняемым образом, поскольку он имеет весь необходимый машинный код, но еще не находится в целевой системе. Этот исполняемый образ будет передан в HCS12 после еще одного преобразования.
<р>4. На следующем шаге мы преобразуем абсолютный файл .abs в форму, пригодную для использования загрузчиком. Загрузчик — это программа, которая переносит исполняемую программу с ПК на HCS12. Загрузчик требует, чтобы исполняемый машинный код в .abs-файле был отформатирован определенным образом. Мы делаем это путем преобразования информации об исполняемом машинном коде в файле .abs в короткие фрагменты кода, называемые Motorola «S-записями». Каждая S-запись представляет собой строку текста, содержащую заголовок, адрес, по которому будет загружен машинный код, сам машинный код и несколько дополнительных битов контрольной суммы, чтобы убедиться, что передача прошла успешно. Конечная программа, которую мы загрузим в HCS12, состоит из набора этих S-записей в одном файле с расширением «.s1» или «.sx». Программа Code Warrior, которая преобразует файл .abs в формат файла .s1/.sx, называется программой записи. Он ссылается на командный файл с расширением «.bbl» (для языка пакетной записи), который подробно сообщает программе записи, как генерировать S-запись. Более подробно S-записи описаны здесь. <р>5. Наконец, мы должны передать файл .s1 с хост-компьютера на целевой микроконтроллер HCS12. Это делается с помощью программы под названием загрузчик. Существует несколько типов загрузчиков в зависимости от соединения между хост-компьютером и целевой системой, а также в зависимости от формата передаваемого файла.Загрузчиком является программа D_bug12 «загрузки», которая считывает S-записи файла .s1 и передает машинный код в нужные ячейки памяти в HCS12. D-Bug12 делает это, передавая по одной строке с ПК на HCS12, причем каждая строка является одной из S-записей файла .s1. Для каждой S-записи машинный код переносится в нужную ячейку памяти на HCS12, а затем проверяется передача строки, чтобы убедиться в отсутствии ошибок. Затем передается следующая строка. Когда загрузчик успешно завершил передачу, теперь у вас есть исполняемая программа, находящаяся на HCS12, которую можно запустить. Обратите внимание, что если мы используем Симулятор, нам не нужно создавать файлы .s1 или .sx, поскольку он напрямую использует файлы .abs. <р>6. Как только исполняемая программа находится в памяти HCS12, мы можем запустить ее по желанию. Если мы используем D-Bug12, мы просто используем команду «>go $address», где «$address» — это шестнадцатеричный адрес, с которого начинается выполнение программы. Значение «$address» загружается в регистр счетчика программ и соответствует адресу памяти, где находится первая строка кода в программе. В качестве альтернативы программа может быть загружена в ПЗУ, чтобы при перезагрузке или включении HCS12 он автоматически переходил к началу программы и начинал там выполнение кода.Подводя итог, чтобы создать исполняемую программу, которая будет работать на HCS12, необходимо: (1) создать текстовый файл с исходным кодом сборки; (2) собрать это в объектный файл с помощью ассемблера; (3) связать объектный файл с абсолютным файлом с помощью компоновщика; (4) преобразовать абсолютный файл в формат s-записи с помощью программы записи; (5) загрузить s-запись в HCS12 с помощью Hyperterminal и команды «загрузить» D-Bug12; (6) и, наконец, когда исполняемая программа находится в памяти HCS12, ее можно запускать по желанию. Кроме того, вы можете имитировать запуск и отладку программы, открыв файл .abs непосредственно в симуляторе. Шаги графически показаны на рисунке ниже для одного исходного файла .asm с использованием абсолютной сборки. Обратите внимание, что компоновщик игнорируется, если используется абсолютная сборка.
Многие типы файлов связаны с проектами Visual Studio для классических настольных приложений. Фактические файлы, включенные в ваш проект, зависят от типа проекта и параметров, выбранных вами при использовании мастера.
При создании проекта Visual Studio вы можете создать его в новом решении или добавить проект в существующее решение. Нетривиальные приложения обычно разрабатываются с несколькими проектами в решении.
Проекты обычно создают либо EXE, либо DLL. Проекты могут зависеть друг от друга; в процессе сборки среда Visual Studio проверяет зависимости как внутри проектов, так и между ними. Каждый проект обычно имеет основной исходный код. В зависимости от типа проекта он может содержать много других файлов, содержащих различные аспекты проекта. Содержимое этих файлов указывается расширением файла. Среда разработки Visual Studio использует расширения файлов, чтобы определить, как обрабатывать содержимое файла во время сборки.
В следующей таблице показаны распространенные файлы в проекте Visual Studio и указаны их расширения.
Расширение файла | Тип | Содержание |
---|---|---|
.asmx | Исходный код | Файл развертывания. |
.asp | Исходный код | < td>Файл страницы активного сервера.|
.atp | Проект | Файл проекта шаблона приложения. |
.bmp, .dib, .jpg, .jpg, .jpe, .jpg | Ресурс | Общие файлы изображений. |
.bsc | Компиляция | Файл кода браузера. |
.cpp, .c td> | Исходный код | Основные файлы исходного кода для вашего приложения. |
.cur | Ресурс | < td>Растровый графический файл курсора.|
.dbp | Проект | Файл проекта базы данных. |
.disco | Источник | Файл документа динамического обнаружения. Обрабатывает обнаружение веб-службы XML. |
.exe, .dll | Project | Исполняемые файлы или файлы библиотеки динамической компоновки. td> |
.h | Исходный код | Файл заголовка (включения). |
.htm, .html, .xsp, .asp, .htc, .hta, .xml | Ресурс | Общие веб-файлы. |
.HxC | Project | Файл проекта справки. |
.ico | Ресурс | td>Растровый графический файл значка. |
.idb | Компиляция | Файл состояния, содержащий информацию о зависимости между исходным файлы и определения классов. Он может использоваться компилятором во время инкрементной компиляции. Используйте параметр компилятора /Fd, чтобы указать имя файла .idb. |
.idl | Компиляция | Определение интерфейса языковой файл.Дополнительные сведения см. в разделе Файл определения интерфейса (IDL) в Windows SDK. |
.ilk | Linking | Файл инкрементной ссылки . Для получения дополнительной информации см. /INCREMENTAL. |
.map | Linking | Текстовый файл, содержащий информацию о компоновщике. Используйте параметр компилятора /Fm, чтобы указать имя файла карты. Для получения дополнительной информации см. /MAP. |
.mfcribbon-ms | Ресурс | Файл ресурсов, содержащий XML-код, определяет кнопки, элементы управления и атрибуты MFC на ленте. Дополнительные сведения см. в разделе Дизайнер ленты. |
.obj, .o | Файлы объектов, скомпилированные, но не связанные. | |
.pch | Debug | Предварительно скомпилированный заголовочный файл. |
.rc, .rc2 | Ресурс | Файлы сценариев ресурсов для создания ресурсов. |
.sbr | Компиляция | Источник промежуточный файл браузера. Входной файл для BSCMAKE. |
.sln | Solution | Файл решения. | .suo | Solution | Файл опций решения. |
.txt | Ресурс | Текстовый файл, обычно файл "readme". |
.vap | Проект | Файл проекта Visual Studio Analyzer. |
.vbg | Solution | Файл совместимой группы проектов. | tr>
.vbp, .vip, .vbproj | Project | Файл проекта Visual Basic. |
.vcxitems | Project | Проект Shared Items для совместного использования файлов кода между несколькими проектами C++. Дополнительные сведения см. в разделе Файлы проекта и решения. |
.vcxproj | Project | Файл проекта Visual Studio. Дополнительные сведения см. в разделе Файлы проекта и решения. |
.vcxproj.filters | Project | Используется при использовании обозревателя решений для добавить файл в проект. Файл фильтров определяет место в представлении дерева обозревателя решений для добавления файла в зависимости от его расширения имени файла. |
.vdproj | Project | Файл проекта развертывания Visual Studio. |
.vmx | Project | Файл проекта макроса. |
.vup | Project | Файл проекта утилиты. |
Файлы проекта организованы в папки в обозревателе решений. Visual Studio создает папку для исходных файлов, файлов заголовков и файлов ресурсов, но вы можете реорганизовать эти папки или создать новые. Вы можете использовать папки для организации явно логических кластеров файлов в иерархии проекта. Например, вы можете создать папки для хранения всех исходных файлов пользовательского интерфейса. Или папки для спецификаций, документации или наборов тестов. Все имена папок с файлами должны быть уникальными.
Добавляя элемент в проект, вы добавляете его во все конфигурации этого проекта. Элемент добавляется независимо от того, можно ли его построить или нет. Например, если у вас есть проект с именем MyProject, при добавлении элемента он добавляется как в конфигурации проекта "Отладка", так и в конфигурацию "Выпуск".
Читайте также: