机器级语言包括机器语言和汇编语言。
机器语言是计算机能直接识别和执行的一种低级语言,使用二进制代码表示,是计算机的基础指令集。汇编语言也是一种低级语言,它使用助记符代替机器语言的二进制代码,使得编程更接近自然语言,但仍然需要被翻译成机器语言才能被计算机执行。这两种语言都是机器级语言,因为它们都是计算机直接执行的语言,不需要经过高级语言的翻译过程。
我们用高级语言编写程序,程序的运行需要将高级语言转化为汇编语言,然后转化为机器语言(二进制)。
那么高级语言为什么不直接转化成机器语言?
高级语言不直接转化为机器语言的主要原因是为了优化和调试的方便,以及为了提高编译器的效率和灵活性。 编译器通常会将高级语言源代码转换成中间代码,然后对中间代码进行优化以提高程序的执行效率,最后将优化后的中间代码转换成目标机器的机器语言代码。在某些情况下,编译器也可能选择生成中间形式的代码(如汇编语言或字节码),这些代码随后再由其他工具(如汇编器或虚拟机)转换成机器语言。
首先,将高级语言转化为汇编语言再转化为机器语言有以下优点:
-
优化和调试方便:汇编语言是机器指令的助记符,一个汇编指令对应一条机器指令,这样调试和优化都更为方便。此外,汇编语言书写较短,机器语言则由一长串的0和1组成,汇编语言更易于阅读和理解。
-
提高编译器的效率:通过生成中间代码,编译器可以更有效地进行代码优化和转换,减少直接从高级语言到机器语言的复杂映射过程。
-
增加灵活性:某些编译器(如Java编译器)生成中间字节码,这些字节码可以在不同的平台上由Java虚拟机(JVM)解释执行,从而实现跨平台兼容性2。
-
保持执行效率:编译方式生成的程序执行效率高,因为整个程序在执行前已经被完全翻译和优化。解释方式虽然灵活,但执行效率相对较低。
此外,编译器的转换过程包括以下几个阶段:
-
词法分析:逐个读取源代码中的字符产生助记符表。
-
语法分析:分析单词符号串是否能够形成指令。
-
语义检查和中间代码生成:对语句进行检查,确保没有二义性,并生成中间代码。
-
代码优化:对程序进行多种等价变换,提升代码运行效率。
-
目标代码生成:将中间代码转换成目标代码并存储在计算机中。
汇编语言如何转化成机器语言
汇编器是一种软件工具,位于计算机的操作系统中。 汇编器的主要功能是将汇编语言源代码转换为机器语言指令,使得计算机能够理解和执行这些指令。汇编语言是一种低级语言,使用助记符来表示机器指令,因此汇编器需要将汇编语言指令转换为二进制代码,生成可执行文件。不同操作系统的汇编语言不同例如Windows和Linux,尽管它们都使用x86/x86-64指令集,但语法和格式存在显著差异。
windows和linux汇编语言的区别:
首先,Windows下的汇编语言主要遵循Intel语法,而Linux下的汇编语言则遵循AT&T语法。这两种语法的区别体现在多个方面:
-
操作数的赋值方向:在Intel语法中,第一个操作数是目的操作数,第二个是源操作数;而在AT&T语法中,第一个操作数是源操作数,第二个是目的操作数。
-
指令前缀:AT&T语法要求在寄存器前加“%”,立即数前加“$”,而Intel语法没有这些要求。
-
内存单元操作数:Intel语法使用“[]”包围基地址,而AT&T语法使用“()”。
-
操作码的后缀:AT&T语法在操作码后面加后缀字母表示位数(如“l”表示32位,“w”表示16位,“b”表示8位),而Intel语法在操作数前面加“dword ptr”、“word ptr”、“byte ptr”来表示。
-
跳转指令标号后缀:AT&T语法中跳转指令标号后有后缀表示跳转方向,“f”表示向前,“b”表示向后。
此外,汇编语言的使用场景和系统支持也有所不同。Linux内核和GCC编译器主要使用AT&T语法,虽然Intel语法也被支持,但与Windows下的MS汇编器仍有区别。汇编语言中常涉及系统中断等指令,不同操作系统提供的功能不同,即使语法正确也可能无法运行。
Windows汇编语言
Windows汇编语言指令集主要包括以下几类指令:数据传送指令、算术运算指令、逻辑运算指令、移位和循环移位指令、条件转移指令、无条件转移指令、调用和返回指令。
数据传送指令
数据传送指令用于将数据从一个位置复制到另一个位置,或者将数据压入堆栈。常见的数据传送指令包括:
-
MOV:将数据从一个位置复制到另一个位置,例如 MOV AX, BX。
-
PUSH:将数据压入堆栈,例如 PUSH AX。
-
POP:从堆栈弹出数据,例如 POP CX。
算术运算指令
算术运算指令用于执行加、减、乘、除等算术操作。常见的算术运算指令包括:
-
ADD:将两个操作数相加,例如 ADD AX, BX。
-
SUB:从一个操作数减去另一个操作数,例如 SUB CX, DX。
-
MUL:无符号整数乘法,例如 MUL AX。
-
DIV:无符号整数除法,例如 DIV BX。
逻辑运算指令
逻辑运算指令用于执行逻辑与、逻辑或、逻辑非等操作。常见的逻辑运算指令包括:
-
AND:对两个操作数进行逻辑与操作,例如 AND AX, BX。
-
OR:对两个操作数进行逻辑或操作,例如 OR CX, DX。
-
XOR:对两个操作数进行逻辑异或操作,例如 XOR AX, BX。
移位和循环移位指令
移位和循环移位指令用于将操作数的位向左或向右移动指定的位数。常见的移位指令包括:
-
SHL:将操作数向左移动指定的位数,例如 SHL AX, 1。
-
SHR:将操作数向右移动指定的位数,例如 SHR BX, 2。
条件转移指令和无条件转移指令
条件转移指令根据条件的真假进行跳转,无条件转移指令则不根据条件直接进行跳转。常见的转移指令包括:
-
JZ:如果结果为零则跳转,例如 JZ label。
-
JE:如果相等则跳转,例如 JE destination。
-
JMP:无条件跳转,例如 JMP target。
调用和返回指令
调用和返回指令用于调用子程序和从子程序返回。常见的调用和返回指令包括:
-
CALL:调用一个子程序,例如 CALL subroutine。
RET:从子程序返回,例如 RET。