; ----------------------------------------------------------------------------
; helloworld.asm
;
; This is a Win32 console program that writes "Hello, World" on one line and
; then exits. It needs to be linked with a C library.
; ----------------------------------------------------------------------------
global _main
extern _printf
section .text
_main:
push message
call _printf
add esp, 4
ret
message:
db 'Hello, World', 10, 0
你需要它吗?
如今,计算机已经变得非常复杂,有几十层抽象。甚至现代处理器的 ISA 指令也不是原子实体,并且处理器将每条指令作为一组更小的指令执行 -微操作(微操作由此类微操作组成)。
裸机
每个特定处理器(例如,Intel Core i3-4160 或 ARM Cortex-A9)都有自己的微架构并实现指令集架构。
微架构在电子元件和逻辑门级别定义处理器的结构。
指令集级架构 (ISA)粗略地定义了处理器可以执行的指令。这种架构是从微架构中抽象出来的。来自不同社区的处理器可能实现相同的架构(例如,许多 Intel 和 AMD 处理器实现相同的x86系列架构)。
如果两个处理器实现相同的 ISA,那么它们可以执行相同的程序。ISA 定义了程序员可以使用哪些命令,可以使用哪些寄存器,如何使用分页、虚拟内存等。此外,它还定义了处理器可以理解的命令格式。
每个处理器程序只是一组连续的指令。当它启动时,处理器从内存中的一个称为复位向量的地址处选择一条指令,并开始执行该程序,直到电源关闭。
用机器代码编写程序非常简单——您只需要获取处理器实现的 ISA 参考(例如,英特尔 64 和 IA-32 架构软件开发人员手册)并逐字节编写必要的指令。
当然,在我们这个时代,没有人用机器代码编写代码,因为一个人很难处理大量的数字和复杂的指令格式(尤其是在 x86 中)。由于这种复杂性,已经创造了汇编语言,它为处理器指令引入了简单的助记符。
例如,一条 x86 汇编指令
MOV可以编码大约 20 条不同的处理器指令MOV1。汇编程序读取您的汇编语言程序并将其转换为二进制文件2,该文件再次只是对连续处理器指令进行编码的字节序列。这是汇编语言程序的摘录可能如下所示:
这是机器语言程序的样子:
显然,汇编代码更易于阅读和编写。
现在你有足够的知识可以像打开字典一样打开参考书,用机器码编写程序并在处理器上执行它。但是,如果您想编写一个可以在任何操作系统上运行的程序,这将不起作用。
操作系统
操作系统是另一个抽象层次,它完全剥夺了我们无限期使用处理器的能力,迫使它执行我们的任何命令3。操作系统做了很多不同的事情,但让我们只关注一个——运行可执行文件。
正如我所说,每个处理器程序只是一个指令序列,但每个操作系统程序都是一个特殊的字节序列,它具有特殊的结构,不仅包括处理器指令。
以 Windows 10 为例,它适用于具有称为Portable Executable
.exe的特殊格式的可执行文件。它有一个相当复杂的结构。除了实际的机器指令集之外,它还包含确定段的地址和大小、导入和导出表、特殊签名等所需的信息。因此,例如,为了手动编写将在 Windows 10 上运行的机器代码程序,我们除了编写程序本身外,还需要将其转换为可移植可执行文件格式。
但即使这样也不够。我们必须熟悉称为ABI的约定,并使用这些约定而不是其他约定用机器代码编写程序。
这里有必要将所有拼图拼凑在一起:程序必须对处理器有效,二进制文件的格式必须是操作系统可以理解的,程序必须能够与操作系统正确通信等。如果您在十六进制编辑器中编写程序,这一切都很难确保。
您可以从用汇编语言编写程序开始(是的,您还必须学习特定汇编语言的语法和英特尔或 AT&T的方言)。NASM中的“Hello, World”如下所示:
你需要它吗?
如今,计算机已经变得非常复杂,有几十层抽象。甚至现代处理器的 ISA 指令也不是原子实体,并且处理器将每条指令作为一组更小的指令执行 -微操作(微操作由此类微操作组成)。
事实上,用汇编语言(尤其是机器语言)编写的能力是毫无用处的。能够简单地阅读和理解汇编程序列表更加实用,并且可以真正派上用场。
这首先是不切实际的,因为没有什么比“你好,世界!”更复杂的了。在机器代码中你不会写。在汇编器中 - 是的,您可以编写它,但要花大量时间在上面,这些时间可以花在更有用的事情上。
1. 有趣的是,
MOVx86 中的指令是图灵完备的,即任何程序都可以单独使用该指令编写。甚至还有一个只使用这一条指令的特殊编译器。2. 一些汇编程序可以立即生成所需格式的可执行文件。包括便携式可执行文件。
3. 我说的是现代操作系统,如 Windows 或 Linux。