过去一周左右,我一直在尝试在 64 位 Windows 7 机器上学习 x86 汇编语言,以更深入地了解计算机的运行方式。
不幸的是,我取得的进展很小,因为许多汇编程序允许使用高级构造和宏以及包含预先编写的代码。这不是问题,直到我意识到我能找到的关于这个主题的所有文档和教程都坚持使用这些抽象、拐杖和混淆,这违背了我想要学习一门真正低级语言的整个目的。
所以现在我正在寻找一种“纯”汇编程序或语言,一种没有高级汇编语言的臃肿和笨拙,并且尽可能接近机器代码的语言。
直接在十六进制编辑器中编写您的 x86 机器代码。
完全有可能,我已经做过很多次了。但是您很快就会了解那些“抽象、拐杖和混淆”的价值,尤其是当您必须手动重新计算第 1000 次跳转偏移时......
看看 NASM。
NASM 有许多您可以定义的高级辅助函数和宏,但您完全可以避免使用它们。
然而,您可能会遇到的一个问题是汇编语言编译为字节,但操作系统总体上不运行字节,它们运行程序。因此,您几乎可以肯定必须弄乱一些更高级别的结构,以说服您最终选择的任何汇编程序生成 PE 文件 (Windows) 或 ELF 文件 (Linux)。
对于纯汇编代码,您可以查看一些基本的 hello world 引导加载程序。引导加载程序不依赖于操作系统调用,而是直接调用 bios。您可以以这个基本教程为例, http: //viralpatel.net/taj/tutorial/hello_world_bootloader.php。这是 16 位汇编。
“纯”有几个层次。例如,当你使用特定的操作系统时,你必须使用它的 API 来进行输入/输出、内存分配等。这个 API 调用是通过不同的方式提供的——有些很容易,有些则不那么容易。
例如,如果您在 Windows 上工作,则必须从系统 DLL 中导入函数。但是函数导入不能算是“汇编编程”。
这些函数的调用约定是 C/C++/HLL,因此,您必须使用此调用约定,而不是更像汇编。
因此,您首先需要对组装友好的操作系统。我建议使用 32 位 Linux - 它使用 int $80 和寄存器参数传递,因此您将能够专注于汇编语言。
这是用 FASM 编写的非常简单的“hello world”示例。如您所见,开销很小,并且不涉及任何宏:
format ELF executable
entry _start
segment readable executable
_start:
mov eax, 4
mov ebx, 1
mov ecx, msg
mov edx, msg_size
int $80
mov eax, 1
xor ebx, ebx
int $80
segment readable writeable
msg db 'Hello world!',$0a
msg_size = $ - msg
当然你需要一些 Linux 系统调用手册。Linux x86 Asm 软件开发工具包正是您所需要的。