如何创建可执行文件以在某个处理器体系结构(而不​​是某些操作系统)上运行?

Gor*_*son 6 c c++ executable compilation processor

所以我在Visual Studio中使用我的C++程序,编译,它会吐出一个漂亮的小EXE文件.但是EXE只能在windows上运行,我听到很多关于C/C++如何编译成汇编语言的东西,它直接在处理器上运行.EXE在Windows的帮助下运行,或者我可以有一个程序来生成在mac上运行的可执行文件.但是我不是将C++代码编译成汇编语言,这是特定于处理器的吗?

我的见解:

  1. 我猜我可能不是.我知道有一个英特尔C++编译器,所以它会制作特定于处理器的汇编代码吗?EXE在Windows上运行,因此它们已经建立了很多东西,从图形包到大规模的.NET框架.特定于处理器的可执行文件将从头开始,仅使用处理器的指令集.

  2. 这个可执行文件是文件类型吗?我们可以运行Windows并打开它,但之后只能控制切换到处理器?我假设这个可执行文件类似于操作系统,因为它必须在启动任何其他操作之前运行,并且只有处理器指令设置为"use".

S.L*_*ott 17

Let's think about what "run" means...

Something has to load the binary codes into memory. That's an OS feature. The .EXE or binary executable file or bundle or whatever, is formatted in a very OS-specific way so that the OS can load it into memory.

Something has to turn control over to those binary codes. There's the OS, again.

The I/O routines (in C++, but this is true in most places) are just a library that encapsulate OS API's. Drat that OS, it's everywhere.

Reminiscing.

在过去(是的,我已经老了)我在没有操作系统的机器上工作.我们也没有C.

我们使用"汇编程序"和"链接器"等工具编写机器代码,以创建可以加载到机器中的大型二进制映像.我们不得不通过痛苦的引导过程加载这些二进制图像.

我们使用前面板键将足够的代码加载到内存中,以读取像打孔纸带读取器这样的便携式设备.这将加载一小块相当标准的引导链接加载器软件.(我们使用聚酯薄膜胶带,因此不会磨损.)

然后,当我们在内存中有这个链接加载器时,我们可以用汇编程序提供我们之前准备的磁带.

我们编写了自己的设备驱动程序 或者我们使用源代码形式的库例程,在纸带上打孔.

A "patch" was actually patched pieces of paper tape. Plus, since there were also little bugs, we'd have to adjust the memory image based on hand-written instructions -- patches that hadn't been put into the tape.

Later, we had simple OS's that had simple API's, simple device drivers, and a few utilities like a "file system", an "editor" and a "compiler". It was for a language called Jovial, but we also used Fortran sometimes.

We had to solder serial interface boards so we could plug in a device. We had to write device drivers.

Bottom Line.

You can easily write C++ programs that don't require an OS.

  1. Learn about the hardware BIOS (or BIOS-like) facilities that are part of your processor's chipset. Most modern hardware has a simple OS wired into ROM that does power-on self-test (POST), loads a few simple drivers, and locates boot blocks.

  2. Learn how to write your own boot block. That is the first proper "software" thing that's loaded after POST. This isn't all that hard. You can use various partitioning tools to force your boot block program onto a disk and you'll have complete control over the hardware. No OS.

  3. Learn how GRUB, LILO or BootCamp launch an OS. It's not complicated. Once they're booted, they can load your program and you're off and running. This is slightly simpler because you create the kind of partition that a boot loader wants to load. Base yours on the Linux kernel and you'll be happier. Don't try to figure out how Windows boots -- it's too complicated.

  4. Read up on ELF. http://en.wikipedia.org/wiki/Executable_and_Linkable_Format

  5. Learn how device drivers are written. If you don't use an OS, you'll need to write device drivers.


Dav*_*kle 6

问题是操作系统真的可以启动你的程序.EXE文件本身具有Windows识别的标题信息,将自身标识为EXE文件.您的应用程序可以完成所有操作,从文件系统访问到内存分配,再到操作系统.

但是,您可以在其他平台上运行为Windows/intel编译的应用程序,而无需进行仿真.如果要在Mac或UNIX上运行EXE,则需要安装更多软件才能完成Windows运行程序所需的工作 - 查看"Wine"项目.


Bro*_*ses 5

你所谈论的是嵌入式世界中所谓的"裸机"应用程序.对于像ARM Cortex-M3这样的东西来说,它们很常见,比如说借记卡验证器盒或交互式玩具,并且没有足够的内存或能力来运行完整的操作系统.因此,您可以获得一个"ARM裸机"编译器来编译在没有操作系统的ARM处理器上运行的东西,而不是获得一个"ARM/Linux"编译器来编译在ARM处理器上的Linux上运行的应用程序.(我使用ARM而不是x86作为示例,因为x86裸机应用程序现在非常罕见.)

如您的问题和其他答案中所述,您的应用程序将需要执行一些操作系统将要处理的事情.

首先,它需要初始化存储器系统,中断向量和各种其他位板.通常这是裸机编译器会为你做的事情,但如果你有一个奇怪的板,你可能需要告诉它如何做到这一点.这可以从电路板打开的位置到main()函数启动的位置.

然后,您需要与CPU和RAM之外的事物进行交互.操作系统包括各种功能 - 磁盘I/O,屏幕输出,键盘和鼠标输入,网络等,等等.没有操作系统,您必须从其他地方获取.您可以从硬件制造商的库中获得一些; 例如,我最近玩的一块电路板有一个40x200像素的LED屏幕,它带有一个带有代码的库,可以打开它并在其上设置单独的像素值.并且有几家公司出售库来实现TCP/IP堆栈等等,用于做网络或诸如此类的事情.

例如,考虑到这使得即使是基本的printf也很难.当你有一个操作系统时,printf只是向操作系统发送一条消息,说"把这个字符串放在控制台上",然后操作系统在控制台上找到当前光标位置,然后做所有的东西来弄清楚什么是像素在屏幕上进行更改,以及用于更改这些像素的CPU指令,以便执行此操作.

哦,我们是否提到你首先必须弄清楚如何让程序进入CPU?典型的计算机有一些可编程ROM,它会在启动时加载指令.在x86上,这是BIOS,它通常已经包含一个方便的程序,可以启动CPU,设置显示,查找磁盘,并从它找到的磁盘上加载程序.在嵌入式系统上,这通常是您的程序所在的位置 - 这意味着您需要某种方式将程序放在那里.通常,这意味着您有一个称为"调试器"的设备,它与物理连接到加载程序的嵌入式板 - 并且还可以执行允许您暂停处理器并确定其状态的设备,这样您就可以像在计算机上的软件调试器中运行一样来完成程序.但我离题了.

无论如何,为了回答你的第二个问题,你创建的这个可执行文件存储在嵌入式板上的ROM中 - 或者你可能只是将它存储在ROM中(毕竟,它很漂亮)小的)并将其余部分存储在闪存驱动器上,ROM中的位将包含将其余部分从闪存驱动器上移除的指令.它可能会作为文件存储在您的主计算机上(即您正在创建它的Linux或Windows计算机上),但这只是用于存储,它不会在那里运行.

你会注意到,当你将很多这些库放在一起时,它们正在做一些操作系统所做的事情,并且在这些库和一个真正的操作系统之间存在着这样的空间.在那个空间里就是所谓的RTOS - "实时操作系统".其中较小的只是库的集合,它们一起工作来完成所有操作系统的事情,有时还包含一些东西,这样你就可以一次运行多个线程(然后你可以让不同的线程像不同的程序一样) - - 尽管所有这些都被编译成相同的编译"程序",而RTOS实际上只不过是你所包含的库.较大的开始将代码的一部分存储在不同的位置,我认为其中一些甚至可以从磁盘上加载一些代码 - 就像Windows和Linux在运行程序时那样.它是一种连续统一体,而不是一种/或者.

FreeRTOS系统是一个开源RTOS,面向RTOS空间的较小端; 如果你更感兴趣,他们可能是一个看待其中一些的好地方.他们确实有一些x86应用程序的例子,它们可以让你了解什么样的x86系统运行一个基于裸机或基于RTOS的程序,以及你如何编译运行在一个上的东西; 链接到这里:http://www.freertos.org/a00090.html#186.