69

我真的很想学习汇编。我非常擅长 c/c++,但希望更好地了解较低级别的情况。

我意识到以前曾提出过与装配相关的问题,但我只是在寻找一些特别适合我的情况的方向:

我正在运行 Windows 7,并且对如何开始使用程序集感到困惑。我是否必须从 x64 开始,因为我正在运行 Windows 7?有人说“先从 32 位开始”——我该怎么做呢?我的操作系统与我为“32”或“64”位编写程序集的能力有什么关系。实际上,“n 位”汇编是什么意思,其中 n 是一个数字?


编辑:

以下是一些帮助我开始组装的链接;其他刚入门的人可能会发现它们很有帮助。当我继续我的组装之旅时,我会不断更新这个列表:)

注意:正如我一直在学习的那样,我决定专注于使用 masm32 进行编程。因此,以下大部分资源都集中在这一点上。

  • 标记 wiki(初学者指南、参考手册、ABI 文档等。)
  • www.masm32.com
  • X86 组装维基书
  • X86 Dissassembly WikiBook(非常适合理解一些约定,以及高级代码如何转换为汇编的基础知识)
  • WinAsm IDE(与 masm32 配合得很好)
  • 简介:Windows 程序集(所有代码示例均适用于 masm32)
  • 中断列表
  • 装配教程(非常有助于理解核心概念)
  • x86 组装指南
  • Agner Fog 的软件优化资源,包括一些关于在不同平台(Windows 与 Linux/OS X)上调用约定的好东西,以及许多如何有效地做特定事情的例子。不适合初学者,但适合中高级读者。

    (他还为 Intel 和 AMD CPU 的每条指令提供了详细的性能信息,非常适合进行认真的性能微优化。一些初学者可能想看看其中的一些内容,以开始思考 CPU 的工作原理,以及为什么你可能会做某事方式而不是另一种方式。)

4

5 回答 5

43

当人们提到32-bit64-bit组装时,他们在谈论您将使用哪个指令集 - 他们有时也被称为Ia32x64在英特尔的情况下,我想您正在询问。在 64 位的情况下还有很多事情要做,所以从 32 位开始可能是好的;您只需要确保使用 32 位汇编器将程序汇编为 32 位二进制文​​件。Windows 仍然会知道如何运行它。

对于开始组装,我真正建议的是使用更简单的指令集来处理。去学习MIPS 组装-spim模拟器很棒而且易于使用。如果您真的想直接进入英特尔汇编世界,请为自己编写一个小 C 程序,为您调用您的汇编例程;为“真正的程序”做所有的设置和拆卸是一团糟,你甚至无法从那里开始。因此,只需在其中编写一个 C 包装器main(),然后将其编译并链接到您从编写汇编代码中获得的目标文件。

请不要养成在 C 代码中编写内联汇编的习惯——这是代码可移植性的噩梦,而且没有理由这样做。

您可以下载所有Intel 64 和 IA-32 架构软件开发人员手册以开始使用。

于 2010-02-28T18:22:52.090 回答
33

我从 1977 年开始编写汇编代码,走的是一条漫长的道路:首先学习基本运算(与、或、异或、非)和八进制数学,然后为具有 OS/8 和 8k 内存的 DEC PDP-8/E 编写程序。这是在 1977 年。

从那时起,我发现了一些关于如何为我不熟悉的架构学习汇编的技巧。有几个:8080/8085/Z80、x86、68000、VAX、360、HC12、PowerPC 和 V850。我很少编写独立程序,它通常是与系统其他部分链接的函数,通常是用 C 语言编写的。

所以首先我必须能够与需要学习参数传递、堆栈布局、创建堆栈框架、参数位置、局部变量位置、丢弃堆栈框架、返回值、返回和堆栈清理的软件的其余部分交互. 最好的方法是编写一个调用 C 中另一个函数的函数,并检查编译器生成的代码列表。

为了学习汇编语言本身,我编写了一些简单的代码,查看编译器生成的内容并在原始调试器中单步执行。我有指令集手册,所以我可以查找我不确定的指令。

了解的一件好事(除了前面提到的堆栈处理之外)是编译器如何在给定某种高级语言结构的情况下生成机器代码。一个这样的序列是如何将索引数组/结构转换为指针。另一个是循环的基本机器代码序列。

那么什么是“原始调试器”?对我来说,它是一个调试器,它是一个简单的开发包的一部分,它不会试图保护我免受 Visual 调试器等硬件的影响。在其中,我可以轻松地在源代码和汇编调试之间切换。它也可以从开发 IDE 内部快速启动。它没有三千个功能,更有可能是三十个,而这些将是您 99.9% 的时间使用的功能。开发包通常是安装程序的一部分,您单击一次以获得许可证批准,一次用于批准默认设置(当有人考虑并为您完成这项工作时,您不喜欢它吗?)最后一次安装.

我有一个最喜欢的 x86-32 (IA-32) 简单开发环境,那就是 OpenWatcom。您可以在 openwatcom.org 上找到它。

我对 x86-64 (AMD64) 还很陌生,但过渡看起来很简单(就像从 x86-16 迁移到 x86-32 时一样),带有一些额外的噱头,例如额外的寄存器 r8 到 r15,主寄存器是 64 位宽的。我最近刚刚遇到了 XP/64、Vista/64 和 7/64 的开发环境(可能也适用于服务器 OS:s),它被称为 Pelles C (pellesc.org)。它由瑞典的一位 Pelle Orinius 编写和维护,从我使用的几个小时来看,我可以说它注定会成为我对 x86-64 的最爱。我已经尝试过 Visual Express 软件包(它们安装了很多垃圾 - 你知道之后需要卸载多少次吗?超过 20 次)并且还尝试从一个地方获取 gcc 以使用 IDE(eclipse 或其他东西) ) 从另一个。

一旦你走到这一步,你就会遇到一个新的架构,你将能够花一两个小时查看生成的列表,然后几乎知道它与其他架构相似。如果索引和循环结构看起来很奇怪,您可以查看生成它们的源代码,也许还可以查看编译器优化级别。

我想我应该警告你,一旦你掌握了窍门,你会注意到在附近的办公桌、咖啡机、会议、论坛和许多其他地方,会有人等着嘲笑你,取笑你由于您对组装的兴趣,您向您抛出不完整的报价并提供不知情/不称职的建议。他们为什么这样做我不知道。也许他们自己是失败的汇编程序员,也许他们只知道 OO(C++、C# 和 Java)并且根本不知道汇编程序是关于什么的。也许他们“认识”(或他们的朋友认识)“非常好”的人可能在论坛上读过一些东西或在会议上听到过一些东西,因此可以提供一个绝对真理,说明为什么集会完全是浪费时间。在stackoverflow上有很多。

于 2011-02-16T13:12:01.837 回答
3

获取IDA 专业版。这是用于装配的蜜蜂膝盖。

我个人认为 32 位和 64 位之间没有太大区别。这不是关于位,而是关于指令集。当您谈论汇编时,您谈论的是指令集。也许他们暗示 32 位指令集更适合学习。但是,如果这是您的目标,我建议 Donald Knuths 的算法书籍——他们根据 7 位指令集汇编来教授算法:D

对于可移植性问题,我建议您学习如何使用编译器内在函数而不是内联汇编——这将是非嵌入式优化的最佳优化。:D

于 2010-02-28T18:21:12.913 回答
1

但希望更好地了解较低级别的情况

如果您真的想了解 x86/x64 处理器/系统上较低级别发生的所有事情,我真的建议您从基础开始,即 286/386 实模式代码。例如,在 16 位代码中,您被迫使用内存分段,这是一个需要理解的重要概念。今天的 32 位和 64 位操作系统仍然以实模式启动,然后在相关模式之间切换/切换。

但是如果你对应用程序/算法开发感兴趣,你可能不想学习所有低级操作系统的东西。相反,您可以从 x86/x64 代码开始,具体取决于您的平台。请注意,32 位代码也可以在 64 位 Windows 上运行,但反之则不行。

于 2010-02-28T18:26:18.190 回答
0

开始编程 C,(不是 C++ 或 C#)将帮助您基本了解“自己动手”所需的内容,例如寄存器、堆栈帧和数据处理。我获得了计算机科学硕士学位,我最喜欢的主题之一是编译器构建(是的 yacc 和 lex!),它确实帮助我深入了解所有更高级别的语言。我仍然珍惜那些定义我自己的语言并将其编译为低级结构的时刻。事实上,我设计了一种在虚拟处理器上执行的面向对象语言。

所以:学习汇编没有捷径。这可能很乏味。但是很满足。

于 2019-06-23T13:31:28.320 回答