简体   繁体   English

汇编语言如何依赖于操作系统?

[英]How do assembly languages depend on operating systems?

As An assembly language implements a symbolic representation of CPU instructions which are independent on OSes while assemblers are always running under some OS, I was wondering how assembly languages depend on operating systems?由于汇编语言实现了独立于操作系统的 CPU 指令的符号表示,而汇编器总是在某些操作系统下运行,我想知道汇编语言如何依赖于操作系统? For example, will assembly languages be the same for the same CPU with different OSes?例如,对于不同操作系统的同一个 CPU,汇编语言是否相同? Thanks!谢谢!

As others have pointed out, system calls and interrupts are different. 正如其他人指出的那样,系统调用和中断是不同的。 I can think of another few differences. 我可以想到另外一些差异。

The instruction set is the same across all OSes on a given processor, but the executable file format might not be. 在给定处理器上的所有OS上,指令集都相同,但是可执行文件格式可能不同。 For example, on the x86, Windows uses the PE format, Linux uses ELF, and MacOS uses Mach-O. 例如,在x86上,Windows使用PE格式,Linux使用ELF,而MacOS使用Mach-O。 That means that assemblers on those platforms must produce their output in those formats, which is a difference. 这意味着那些平台上的汇编器必须以这些格式产生其输出,这是有区别的。

Relatedly, the calling convention could also be different across different OSes. 相关地,不同操作系统之间的调用约定也可能不同。 That probably only matters where you are writing assembly code that calls or is called by compiled-code routines, or perhaps where you are writing inline assembler in some compiled code. 这可能仅在您编写调用或被编译代码例程调用的汇编代码的地方,或者在某些编译代码中编写内联汇编器的地方才有意义。 The calling convention governs which registers are used for what purposes during a function call, so different conventions require different use of registers by calling and called code. 调用约定控制在函数调用期间将哪些寄存器用于什么目的,因此不同的约定要求通过调用和被调用的代码来不同地使用寄存器。 They also put constraints on the position of the stack pointer, and various other things. 他们还对堆栈指针和其他各种东西的位置施加了约束。 As it happens, calling conventions have historically been a rare example of consistency across OSes in many cases: i believe the Windows and UNIX calling conventions are the same on the x86 (and are all based on the venerable UNIX System V ABI specification), and are consistent across OSes on most other architectures. 碰巧的是,在许多情况下,调用约定在过去一直是跨操作系统一致性的罕见示例:我相信Windows和UNIX调用约定在x86上是相同的(并且都基于古老的UNIX System V ABI规范),并且在大多数其他体系结构上的操作系统之间保持一致。 However, the conventions are now different between Windows and UNIX on the x86_64. 但是,Windows和UNIX在x86_64上的约定现在不同。

In addition, there may be differences in the syntax used by the assembly language. 此外,汇编语言使用的语法可能有所不同。 Again on the x86, the Windows and Linux assemblers used to use different syntax, with the Windows assembler using a syntax invented by Intel, and the Linux assembler (really, the GNU assembler) using a traditional UNIX syntax invented by AT&T. 同样在x86上,Windows和Linux汇编器曾经使用不同的语法,Windows汇编器使用了Intel发明的语法,而Linux汇编器(实际上是GNU汇编器)则使用了AT&T发明的传统UNIX语法。 These syntaxes describe the same instruction set, but are written differently. 这些语法描述了相同的指令集,但写法不同。 Nowadays, the GNU assembler can also understand the Intel syntax, so there is less of a difference. 如今,GNU汇编器也可以理解Intel语法,因此差异不大。

Assembly languages don't depend on an OS, but on the CPU's instruction set. 汇编语言不依赖于操作系统,而是依赖于CPU的指令集。

Only if you call API functions (like for example a Windows API function from inline assembler code in MSVC), you get an OS dependency. 仅当调用API函数(例如MSVC中的内联汇编代码中的Windows API函数)时,您才获得OS依赖项。

The instructions available (and each instruction's semantics, of course) depends on the CPU, not on the OS - so in a way, you are right. 可用的指令(当然还有每条指令的语义)取决于CPU,而不取决于OS-因此从某种意义上来说,您是对的。

But for most tasks of interest (I/O for example), you have to talk to the OS (making system calls). 但是对于大多数感兴趣的任务(例如I / O),您必须与OS对话(进行系统调用)。 Cross-platform abstractions over these things don't exist at that level (well, you could try to use libc for instance, but even then you need to know the calling convention used, which can differ between platforms, etc. - in the end, you'd have to put quite some work into building such an abstraction yourself, so AFAIK few of the few people who program in assembly bother to try), to do something not possible with the (OS-independent) CPU instructions, you have to know what OS you're programming for and how to tell that OS to do it. 在这些级别上不存在跨平台的抽象(嗯,例如,您可以尝试使用libc ,但是即使那样,您仍然需要知道所使用的调用约定,这在平台之间可能会有所不同,等等-最后,您必须自己投入大量工作来构建这样的抽象,因此AFAIK很少有人会尝试使用汇编语言进行编程),以使用(独立于OS的)CPU指令无法完成某些工作,知道您要编程的操作系统以及如何告诉该操作系统。

This doesn't apply as heavily for inline assembly code in eg C code, as it is mostly used to make purely CPU-bound computations in a smarter/faster way than the compiler is expected to). 这不适用于C语言中的内联汇编代码,因为它主要用于以比编译器预期的方法更快或更聪明的方式进行纯粹的CPU绑定计算。

The assembly language should be the same; 汇编语言应该相同; as you point out, the instruction set depends only on the CPU and its architectural design. 如您所指出的,指令集仅取决于CPU及其体系结构设计。 Where you start getting into trouble with different OSs, I believe, is when you start invoking eg interrupts (typically for I/O) which can definitely mean programs written for eg MSDOS won't work on eg Solaris (maybe a bad example). 我相信您开始在不同的操作系统上遇到麻烦的地方是当您开始调用例如中断(通常用于I / O)时,这肯定意味着为MSDOS编写的程序无法在Solaris上运行(也许是一个不好的例子)。

An assembler translates mnemonics (eg jump , mov , add , etc.) from an assembly language into machine instructions. 汇编器将助记符(例如jumpmovadd等)从汇编语言转换为机器指令。 Machine instructions are entirely dependent on the hardware (they represent the hardware/CPU instruction set). 机器指令完全取决于硬件(它们代表硬件/ CPU指令集)。

If you ever wanted to come up with an assembly language, you would need to also design/write an assembler that would do the mapping to machine instructions. 如果您想使用一种汇编语言,则还需要设计/编写一个可以映射到机器指令的汇编器。 In that sense if you target a given machine architecture, the assembler should produce machine specific code, not OS specific code. 从这种意义上讲,如果您针对给定的计算机体系结构,则汇编程序应生成计算机特定的代码,而不是操作系统特定的代码。 However, the assembler implementation may (and generally is ) OS-specific, because of the output program it produces (a Unix executable is not the same as a Windows executable, even though the underlying machine instruction set is x86, for example). 但是, 汇编程序实现可能(并且通常特定于OS的)特定的,因为它生成的输出程序(例如,即使基础机器指令集是x86,Unix可执行文件与Windows可执行文件也不相同)。

See here what I mean. 这里我的意思。

Assembly language has nothing to do with it, you can take your question (how xyz language depends on operating systems) and use C, pascal, ada, fortran, and a long list of other languages and ask the same question with the same answer, the language has nothing to do with it. 汇编语言与之无关,您可以提出问题(xyz语言如何取决于操作系统),并使用C,pascal,ada,fortran和一长串其他语言,并用相同的答案提出相同的问题,语言与它无关。 The system calls into the operating system using the calling convention for the operating system is what matters, IF you are using the same language or a language with the same calling convention as the operating systems definition, that makes life easier but does not lock you into anything. 如果您使用与操作系统定义相同的语言或具有相同的调用约定的语言,则系统使用操作系统的调用约定来调用操作系统是很重要的,这可以使生活更轻松,但不会使您陷入困境任何东西。 pretty much any language can be used as you likely well know, the standards C, C++, etc as well as the virtual or runtime interpreted, etc java, perl, python, shell script, javascript, etc. They all seem to run on my computer at least. 众所周知,几乎可以使用任何语言,标准C,C ++等以及虚拟或运行时解释的语言,例如java,perl,python,shell脚本,javascript等。它们似乎都在我的计算机上运行至少计算机。 Somewhere (language specific) is a shim that makes the system calls into the operating system in a manner defined by the operating system. 某个位置(特定于语言)是一个垫片,它使操作系统以操作系统定义的方式调用操作系统。 Asm makes life easy for some of those languages since you are bound by no rules you can use asm to make that shim between the language calling convention and the operating system call desired. Asm使其中某些语言的生活变得轻松,因为您不受任何规则的束缚,因此可以使用asm在语言调用约定和所需的操作系统调用之间进行填充。 Likewise using asm makes it easy to interface to any calling convention be it language defined or operating system defined. 同样,使用asm可以很容易地连接到任何调用约定,无论是语言定义的还是操作系统定义的。

Also as already answered assembly language is independent of the operating system or any other software running on the cpu. 同样,已经回答的汇编语言也独立于操作系统或CPU上运行的任何其他软件。 it is tied directly to the cpu's instruction set. 它直接与CPU的指令集联系在一起。 Now there is the machine code, the actually bits executed by the processor, those do not change, but the ascii files used to represent those instructions, that language can change but not because of the cpu nor the operating system, those differences have to do with the toolchain. 现在有机器代码,实际上是处理器执行的位,这些没有改变,但是用于表示这些指令的ascii文件,该语言可以改变,但不是因为cpu或操作系统的缘故,所以这些差异必须要做与工具链。 For example x86 att syntax vs intel syntax. 例如x86 att语法与intel语法。 Same instruction set, same machine code, different assembly language. 相同的指令集,相同的机器代码,不同的汇编语言。 and if you look around enough tasm, masm, etc there are many assemblers for x86 and each have their own directives and other toolchain specific nuances. 如果您查看了足够多的tasm,masm等信息,则有很多x86汇编程序,每个汇编程序都有自己的指令和其他特定于工具链的细微差别。

The OS doesn't matter. 操作系统无关紧要。 You could have the same assembler on different OSes, you can use different compilers on the same OS, hey, you can even cross compile, targeting different systems. 您可以在不同的操作系统上使用相同的汇编程序,可以在同一操作系统上使用不同的编译器,嘿,甚至可以针对不同的系统进行交叉编译。

I think LINKER is responsible for making OS specific executable file format adding dynamic link liabaries (.dll) etc. It stamps for specific OS format file to executable ones.我认为 LINKER 负责制作操作系统特定的可执行文件格式,添加动态链接库(.dll)等。它将特定操作系统格式文件标记为可执行文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM