在 Linux、Windows 上运行 Assembly

Posted

技术标签:

【中文标题】在 Linux、Windows 上运行 Assembly【英文标题】:Running Assembly across Linux, Windows 【发布时间】:2012-05-10 12:24:07 【问题描述】:

我一直在阅读有关汇编的信息。从我对编程语言的理解来看,编译器(汇编器......我知道在其他地方争论的两者之间存在细微的差异),生成目标代码。大量没有指令的不友好的机器语言。该目标代码由处理器解释,然后链接器使其成为可执行文件。我知道每个处理器都必须在其正确的组装中进行交谈。 IE。 .386, .486, .586 令我困惑的是通过 MASM 运行 DOS 程序和通过没有 NASM 或 GAS 的 Linux 运行相同程序之间的差异。如果源代码编译成目标代码,此时不是跨平台吗?我可以像 Linux 一样简单地从我的戴尔双启动 Windows。我在这里错过了什么?

我也一直在寻找一种查看目标代码的方法,这样我就不必通过 Immunity Debugger 来破译执行。只是我编写的源代码的指令机器代码指令。有没有办法在 Linux 中产生类似 objdump 的结果?

【问题讨论】:

请don't add signatures or taglines to your posts。 DOS 以(16 位)实模式执行,这与 32 位 Windows/Linux 中使用的保护模式有很大不同。它是如此不同,以至于它可以被认为是不同的架构(如 ARM 与 MIPS),因此它不再是跨平台的。 Windows 使用一种特殊的硬件兼容模式(虚拟模式)来执行 DOS 二进制文件,但在较新的 (x86_64) 系统上,即使这样也不可能了 问题的核心是虽然汇编是低级的,但它仍然必须与操作系统接口。而且由于它的级别有多低,它必须使用最低级别的调用机制与操作系统进行交互,这在操作系统之间是完全不同的。此外,程序集通常直接访问自身进程的内存,根据操作系统的不同,其布局完全不同。你见过 DOS 和 Linux 上命令行参数所需的不同汇编源吗? Is assembly code cross-platform?的可能重复 @Linuxios 是否可以在 windows linux 和 mac 的可执行文件中使用机器代码? 【参考方案1】:

现代的“x86”芯片至少可以理解三种不同的指令集——DOS 使用的 16 位指令集,以及各种 Windows 和 linux 使用的 32 位和 64 位指令集。

即使芯片是相同的,并且可能运行在相同的模式下,程序与主机操作系统交互以获得服务(例如输入/输出)的方式是完全不同的。

除了最琐碎的程序外,所有程序都倾向于使用附加目标代码的外部库,这些库为常见操作(字符串操作、格式化输入和输出、数学、非平凡网络等)提供帮助,因此它们不会必须从头开始编写。但是可用的此类库的精确集合,以及请求和与它们交互的重要方式,因主机操作系统而异。您也许可以将库与您的应用程序一起打包(静态链接),而不是使用 .DLL/.so 期望已经在系统上(动态链接),但仍然需要适应请求底层原始操作系统服务的差异.

此外,一些方案(例如 java 和 .net)创建在虚拟机或模拟处理器上运行的目标代码,而不是直接在物理处理器上运行。如果虚拟机引擎和支持库以兼容的形式提供,那么它们在某种程度上是可移植的。

objdump 的 mingw 版本在 windows 上运行并处理 windows 可执行文件,并且是用于构建具有类 linux 语义的 windows 程序的工具套件的一部分。它还有一个交叉版本,可以在 linux 上运行并处理 windows 文件。反过来说,WINE 兼容层可以在 linux 上运行许多 Windows 可执行文件——你可以明确地对此进行测试。但是,如果您愿意针对 posix 接口用 C 语言编写(或在带有汇编的 OS 函数上使用大量包装器),您应该能够拥有一个代码库,该代码库可以同时使用 linux 和交叉或 mingw 版本的 gnu 工具构建,这样您可以相对有效地为两个操作系统生成二进制文件。

【讨论】:

哇,感谢您提供的信息。这给了我的研究方向。 对于一个完全没有依赖关系,只有机器代码的程序怎么样。有没有办法可以跨平台? @bluejayke 没有没有平台依赖性的程序具有任何价值。如文中所述,程序需要与宿主操作系统或硬件交互来完成输入和输出。否则,它正在运行的事实是无关紧要的。 @ChrisStratton 我不是在谈论一个有价值的程序,我在谈论一个返回值 2 + 2 的程序,理论上有没有办法从终端运行它/来自 3 个操作系统中的任何一个的 CMD? 您完全没有抓住重点-您所描述的是一个具有价值的程序,并且需要main() 的调用和返回约定,该约定指定如何传递和返回参数,即使它确实如此没有其他 I/O,不进行系统调用等,它在调用约定中仍然具有平台依赖性。

以上是关于在 Linux、Windows 上运行 Assembly的主要内容,如果未能解决你的问题,请参考以下文章

linux服务器上的程序下载到本地windows上怎样运行

在Windows上运行Linux

【xming】Windows上安装xming,远程运行Linux图形界面

如何在Linux上运行Windows应用程序

C++ 程序在 Linux 上完美运行,但不能在 Windows 上运行

为啥这段代码可以在 Linux 上运行,但不能在 Windows 上运行?