Как я могу создать исполняемый файл для работы определенной архитектуры процессора (вместо определенной ОС)?

Можно использовать:

Thread.Sleep(1000);

, Который приостановит текущий поток в течение одной секунды. Таким образом, я сделал бы это...

С наилучшими пожеланиями!

6
задан Gordon Gustafson 14 March 2010 в 14:07
поделиться

9 ответов

Давайте подумаем о том, что означает «запускать» ...

Что-то должно загружать двоичные коды в память. Это особенность ОС. .EXE, или двоичный исполняемый файл, или пакет, или что-то еще, форматируется очень специфичным для ОС способом, чтобы ОС могла загружать его в память.

Что-то должно передать контроль этим двоичным кодам. Опять же, ОС.

Подпрограммы ввода-вывода (в C ++, но это верно в большинстве случаев) - это просто библиотека, которая инкапсулирует API ОС. Черт, эта ОС, она везде.

Вспоминая .

В старину (да, я такой старый) я работал на машинах, на которых не было ОС. У нас также не было C.

Мы писали машинные коды, используя такие инструменты, как «ассемблеры» и «компоновщики», для создания больших двоичных образов, которые мы могли загрузить в машину. Нам пришлось загрузить эти двоичные образы через болезненный процесс начальной загрузки.

Мы использовали бы клавиши передней панели, чтобы загрузить в память достаточно кода, чтобы прочитать такое удобное устройство, как устройство для чтения перфоленты. Это загрузит небольшую часть довольно стандартного программного обеспечения загрузчика, связанного с загрузкой. (Мы использовали майларовую ленту, чтобы она не изнашивалась.)

Затем, когда у нас был этот загрузчик ссылок в памяти, мы могли пропустить ленту, которую мы подготовили ранее, с помощью ассемблера.

Мы написали собственные драйверы устройств. Или мы использовали библиотечные подпрограммы, которые были в исходной форме, перфорированы на бумажных лентах.

«Патч» на самом деле представлял собой залатанные кусочки бумажной ленты. Кроме того, поскольку были и небольшие ошибки, нам пришлось бы корректировать образ памяти на основе рукописных инструкций - исправлений, которые не были записаны на ленту.

Позже у нас были простые ОС с простым API ' s, простые драйверы устройств и несколько утилит, таких как «файловая система», «редактор» и «компилятор». Это было для языка под названием Jovial, но мы также иногда использовали Fortran.

Нам пришлось припаять платы последовательного интерфейса, чтобы мы могли подключить устройство. Нам пришлось написать драйверы устройств.

Итог .

Вы можете легко писать программы на C ++, для которых не требуется ОС.

  1. Узнайте об аппаратных средствах BIOS (или подобных BIOS), которые являются частью набора микросхем вашего процессора. Большинство современного оборудования имеет простую ОС, подключенную к ПЗУ, которая выполняет самотестирование при включении (POST), загружает несколько простых драйверов и определяет местонахождение загрузочных блоков.

  2. Узнайте, как написать свой собственный загрузочный блок. Это первая правильная «программная» вещь, загружаемая после POST. Это не так уж и сложно. Вы можете использовать различные инструменты для создания разделов, чтобы принудительно записать программу загрузочного блока на диск, и у вас будет полный контроль над оборудованием. Нет ОС.

  3. Узнайте, как GRUB, LILO или BootCamp запускают ОС. Это не сложно. Как только они загрузятся, они могут загрузить вашу программу, и вы начнете работать. Это немного проще, потому что вы создаете раздел, который загрузчик хочет загрузить. Основывайтесь на ядре Linux, и вы станете счастливее. Не пытайтесь понять, как загружается Windows - это слишком сложно.

  4. Прочтите об ELF. http://en.wikipedia.org/wiki/Executable_and_Linkable_Format

  5. Узнайте, как пишутся драйверы устройств. Если вы не используете ОС, вам нужно будет написать драйверы устройств.

17
ответ дан 8 December 2019 в 02:46
поделиться

Проблема в том, что ОС действительно много делает для запуска ваших программ. В самом EXE-файле содержится информация заголовка, которую Windows распознает, идентифицируя себя как EXE-файл. Ваше приложение делает все, от доступа к файловой системе до распределения памяти через ОС.

Но да, вы МОЖЕТЕ запускать приложения, скомпилированные для Windows / Intel, на других платформах без эмуляции. Если вы хотите запустить EXE-файл на Mac или UNIX, вам нужно будет установить немного больше программного обеспечения, которое будет выполнять ту же работу, что и Windows, - взгляните на проект "Wine".

6
ответ дан 8 December 2019 в 02:46
поделиться

What you're talking about is what's known in the embedded world as a "bare-metal" application. They're very common for things like a ARM Cortex-M3 that goes in (say) a debit-card validator box or an interactive toy, and doesn't have enough memory or capability to run a full operating system. So, instead of getting an "ARM/Linux" compiler that would compile an application to run on Linux on an ARM processor, you get an "ARM bare-metal" compiler that compiles things to run on an ARM processor without an operating system. (I'm using ARM rather than x86 as an example, because x86 bare-metal applications are really quite rare these days.)

As stated in your question and the other answers, your application will need to do some things that would otherwise be taken care of by the operating system.

First, it needs to initialize the memory system, the interrupt vectors, and various other bits of board goo. Typically this is something that a bare-metal compiler will do for you, though if you have a weird board, you may need to tell it how to do that. This gets things from the point where the board turns on to the point where your main() function starts.

Then, you need to interact with things outside the CPU and RAM. An operating system includes all sorts of functions for doing this -- disk I/O, screen output, keyboard and mouse input, networking, etc., so forth, and so on. Without an operating system, you have to get that from somewhere else. You may get some of that from libraries from your hardware manufacturer; for instance, a board I was recently playing with has a 40x200-pixel LED screen, and it came with a library with the code to turn that on and set individual pixel values on it. And there are several companies selling libraries to implement a TCP/IP stack and things like that, for doing networking or whatnot.

Consider, for example, that this makes it difficult to do even a basic printf. When you have an operating system, printf just sends a message to the operating system that says "put this string on the console", and the operating system finds the current cursor position on the console, and does all the stuff to figure out what pixels to change on the screen, and what CPU instructions to use to change those pixels, in order to do that.

Oh, and did we mention that you first have to figure out how to get the program into the CPU? A typical computer has a bit of programmable ROM that it will load instructions from when it starts up. On an x86, this is the BIOS, and it usually already contains a handy program that gets the CPU started, sets up the display, looks for disks, and loads a program off the disk that it finds. On an embedded system, that's typically where your program goes -- which means you need some way to put your program there. Often, that means you have a device called a "debugger" that's physically attached to your embedded board that loads the program -- and can also do things that allow you to pause the processor and determine what its state is, so that you can step through your program just as if you were running it in a software debugger on your computer. But I digress.

Anyway, to answer your second question, this executable that you'd create is something that gets stored in that ROM on your embedded board -- or perhaps you'd just store a bit of it in ROM (which is, after all, pretty small) and store the rest on a flash drive, and the bit in ROM would include the instructions to get the rest of it off the flash drive. It would probably be stored as a file on your main computer (that is, the Linux or Windows computer where you're creating it), but that's just for storage, it wouldn't run there.

You'll notice that when you've got a lot of these libraries together, they're doing a fair bit of what an operating system does, and there's sort of this space between the pile of libraries and a real operating system. In that space goes what's called an RTOS -- "real-time operating system". The smaller ones of these are really just collections of libraries that work together to do all the operating-systemy things, and sometimes also include stuff so you can run multiple threads at once (and then you can have different threads act like different programs) -- though all of this is all compiled into the same compiled "program", and the RTOS is really nothing more than a library you've included. Larger ones start storing parts of the code in separate places, and I think some of them can even load pieces of code off of disks -- just like Windows and Linux do when running a program. It's sort of a continuum, rather than an either/or.

The FreeRTOS system is an open-source RTOS that's towards the smaller end of the RTOS space; they might be a good place to look at some of this if you're more interested. They do have some examples of x86 applications, which would give you an idea of what sort of x86 systems would run a bare-metal or RTOS-based program and how you'd compile something to run on one; link here: http://www.freertos.org/a00090.html#186.

5
ответ дан 8 December 2019 в 02:46
поделиться

The computer is not the CPU. To do anything useful, the CPU has to be connected to memory and IO controllers and other devices. An OS takes care of abstracting all of that from running programs. So, if you want to write a program that runs without an OS, your program will have to replicate at least some features of an OS: Taking over from the BIOS during the boot process, initializing devices, communicating with the disk controller to load code and data, communicating with the display controller to show information to the user, communicating with the keyboard controller and the mouse controller to read user input etc etc etc.

Unless you are building an embedded system with specialized hardware, there is no point in doing this. Besides, running your program would mean the user would have to give up running other programs. While this may be acceptable for an ATM today or WordStar in 1984, these days people frown on not being able to check email while listening to music.

3
ответ дан 8 December 2019 в 02:46
поделиться

Конечно, они существуют. Они называются кросс-компиляторами . Например, вот как я могу программировать для платформы iPhone с помощью Xcode.

Связанный тип компилятора - это компилятор, который компилируется для виртуальной платформы. Так работает Java .

1
ответ дан 8 December 2019 в 02:46
поделиться

Любой данный компилятор / набор инструментов создает код для конкретной комбинации процессора / ОС. Итак, ваш пример компиляции Visual Studio создает код для x86 / Windows. Этот .EXE будет работать только на x86 / Windows, но не на (например) ARM / Windows (как используется некоторыми мобильными телефонами).

Для создания кода для комбинации процессора / ОС, отличной от той, на которой вы запускаете компилятор требует того, что обычно называют кросс-компилятором. Если у вас есть полная профессиональная подписка на Visual Studio, вы можете получить кросс-компилятор ARM, который позволит вам создавать файлы ARM / Windows .EXE, которые не будут работать на вашем настольном компьютере, но БУДУТ работать на мобильном телефоне на базе ARM / Windows. или карманный компьютер.

1
ответ дан 8 December 2019 в 02:46
поделиться

Да, вы можете создать исполняемый файл, работающий на «голом железе» процессора. Очевидно, так работают ядра операционных систем. Главное, что вам нужно сделать, это создать исполняемый файл, который вообще не использует никаких библиотек. Однако ограничение «без библиотек» включает стандартную библиотеку C! Это означает отсутствие malloc, printf и т. Д. Вы должны быть собственной ОС и сами управлять памятью и вводом-выводом. На каком-то этапе это неизбежно потребует изрядной работы непосредственно при сборке.

Вы также теряете некоторые другие предметы роскоши, такие как main (), которая не может быть отправной точкой вашей программы, поскольку main () - это то, что вызывается ОС и средой выполнения C.

0
ответ дан 8 December 2019 в 02:46
поделиться

Основная проблема - это формат файла. PE сильно отличается от ELF (используется в unix-подобных системах). Действительная программа PE не может быть действительным ELF. Таким образом, вы либо загружаете двоичный файл динамически с разными стартерами, либо вам придется отказаться.

Помимо этого, зная службы ОС, значение регистров при запуске и т. Д., Ваш код, вероятно, сможет легко и надежно определить, какая ОС вы работаете и действуете соответственно (некоторые вредоносные программы именно так и поступают). Другой проблемой является повторное использование кода вместо двух или более разных программ в одном двоичном файле. По сути, вам придется написать эмулятор, по крайней мере, для тех служб, которые вам нужны.

0
ответ дан 8 December 2019 в 02:46
поделиться

Совершенно верно! Вот что такое встроенное программирование. Как многие, наверное, уже сказали, операционная система многое для вас делает. И даже во встраиваемом мире без операционной системы ряд инструментов разработки предоставит код запуска, чтобы процессор работал достаточно, чтобы перейти к вашей программе. Некоторые / многие предоставляют полнофункциональные библиотеки C / C ++, так что вы можете вызывать такие функции, как memcpy (), а иногда даже malloc () и printf ().

Вы можете предоставить каждую строку кода и каждую инструкцию и не использовать пакет средств разработки, но по-прежнему использовать компилятор, например, gcc. Некоторые из двоичных форматов являются общими для тех, которые работают в операционных системах, например, в elf. Вы можете выполнять файлы elf в Linux, но также можете получить результат своей встроенной программы в двоичном файле elf. Процессор не может выполнить elf в этом формате, но какие бы программы ни были, в некоторых случаях, программа boot prom или ram будет извлекать двоичную программу из файла elf, в отличие от операционной системы, извлекающей программу для запуска из файла elf. EXE не относится к таким форматам файлов. Ваш любимый компилятор приложений Windows, вероятно, также не является встроенным компилятором, хотя иногда вы можете использовать его для работы с языком высокого уровня, а затем использовать альтернативный ассемблер и компоновщик. Больше работы, чем обычно. Например, вы пишете функцию на C (которая НЕ выполняет никаких библиотечных или системных вызовов), компилируете ее в объект. Напишите свой собственный или найдите утилиту для извлечения скомпилированного двоичного файла из этого объекта, преобразования его в другой формат объекта или в ассемблер (дизассемблер). Добавьте в него свой код запуска и другую сборку. Соберите и соедините все вместе как встроенную программу. Я однажды проделал это со встроенным Visual C от Microsoft, чтобы посмотреть, насколько он соответствует другим компиляторам, это не было ужасно, но, конечно, не стоило усилий взлома, чтобы получить результат.

Каждый процессор, от процессора вашего компьютера до на телефоне или в микроволновой печи тоже есть код загрузки. Этот код не работает в операционной системе. Этот код использует те же или похожие компиляторы, что и приложения операционной системы. Для некоторых устройств этот код переводит процессор и память, а также периферийные устройства на кристалле и за его пределами в состояние, при котором операционная система может быть запущена. Оттуда операционная система вступает во владение. На вашем компьютере это будет BIOS, затем загрузчик, затем операционная система, dos, windows, linux и т. Д.

Я однажды проделал это со встроенным Visual C от Microsoft, просто чтобы посмотреть, насколько он соответствует другим компиляторам, это не было ужасно, но определенно не стоило усилий взлома, чтобы получить результат.

Каждый процессор, от процессора вашего компьютера до на телефоне или в микроволновой печи тоже есть код загрузки. Этот код не работает в операционной системе. Этот код использует те же или похожие компиляторы, что и приложения операционной системы. Для некоторых устройств этот код переводит процессор и память, а также внешние и внешние периферийные устройства в состояние, при котором операционная система может быть запущена. Оттуда операционная система вступает во владение. На вашем компьютере это будет BIOS, затем загрузчик, затем операционная система, dos, windows, linux и т. Д.

Я однажды проделал это со встроенным Visual C от Microsoft, чтобы посмотреть, насколько он соответствует другим компиляторам, это не было ужасно, но, конечно, не стоило усилий взлома, чтобы получить результат.

Каждый процессор, от процессора вашего компьютера до на телефоне или в микроволновой печи тоже есть код загрузки. Этот код не работает в операционной системе. Этот код использует те же или похожие компиляторы, что и приложения операционной системы. Для некоторых устройств этот код переводит процессор и память, а также внешние и внешние периферийные устройства в состояние, при котором операционная система может быть запущена. Оттуда операционная система вступает во владение. На вашем компьютере это будет BIOS, затем загрузчик, затем операционная система, dos, windows, linux и т. Д.

это не было ужасно, но определенно не стоило усилий взлома, чтобы получить результат.

Каждый процессор, от компьютера до процессора сотового телефона или микроволновой печи, тоже имеет код загрузки. Этот код не работает в операционной системе. Этот код использует те же или похожие компиляторы, что и приложения операционной системы. Для некоторых устройств этот код переводит процессор и память, а также периферийные устройства на кристалле и за его пределами в состояние, при котором операционная система может быть запущена. Оттуда операционная система вступает во владение. На вашем компьютере это будет BIOS, затем загрузчик, затем операционная система, dos, windows, linux и т. Д.

это не было ужасно, но определенно не стоило усилий взлома, чтобы получить результат.

Каждый процессор, от компьютера до процессора сотового телефона или микроволновой печи, тоже имеет код загрузки. Этот код не работает в операционной системе. Этот код использует те же или похожие компиляторы, что и приложения операционной системы. Для некоторых устройств этот код переводит процессор и память, а также периферийные устройства на кристалле и за его пределами в состояние, при котором операционная система может быть запущена. Оттуда операционная система вступает во владение. На вашем компьютере это будет BIOS, затем загрузчик, затем операционная система, dos, windows, linux и т. Д.

На каждом процессоре, от компьютера до процессора сотового телефона или микроволновой печи, тоже есть код загрузки. Этот код не работает в операционной системе. Этот код использует те же или похожие компиляторы, что и приложения операционной системы. Для некоторых устройств этот код переводит процессор и память, а также периферийные устройства на кристалле и за его пределами в состояние, при котором операционная система может быть запущена. Оттуда операционная система вступает во владение. На вашем компьютере это будет BIOS, затем загрузчик, затем операционная система, dos, windows, linux и т. Д.

На каждом процессоре, от компьютера до процессора сотового телефона или микроволновой печи, есть код загрузки. Этот код не работает в операционной системе. Этот код использует те же или похожие компиляторы, что и приложения операционной системы. Для некоторых устройств этот код переводит процессор и память, а также внешние и внешние периферийные устройства в состояние, при котором операционная система может быть запущена. Оттуда операционная система вступает во владение. На вашем компьютере это будет BIOS, затем загрузчик, затем операционная система, dos, windows, linux и т. Д.

Для некоторых устройств этот код переводит процессор и память, а также периферийные устройства на кристалле и за его пределами в состояние, при котором операционная система может быть запущена. Оттуда берет на себя операционная система. На вашем компьютере это будет BIOS, затем загрузчик, затем операционная система, dos, windows, linux и т. Д.

Для некоторых устройств этот код переводит процессор и память, а также внешние и внешние периферийные устройства в состояние, при котором операционная система может быть запущена. Оттуда операционная система вступает во владение. На вашем компьютере это будет BIOS, затем загрузчик, затем операционная система, dos, windows, linux и т. Д.

0
ответ дан 8 December 2019 в 02:46
поделиться