要学习汇编 - 我应该从32位还是64位开始?

时间:2010-02-28 18:19:35

标签: assembly x86 x86-64 low-level

我真的很想学习装配。我非常擅长c / c ++,但希望更好地了解较低级别的内容。

我意识到之前已经提出了与装配相关的问题,但我只是在寻找一些特定于我的情况的方向:

我正在运行Windows 7,我对如何开始使用程序集感到困惑。我从x64开始,因为我正在运行Windows 7吗?有些人说“先从32位开始” - 我该如何做呢?我的操作系统与我为'32'或'64'位写入汇编的能力有什么关系。实际上,'n位'汇编意味着什么,其中n是数字??


编辑:

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

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

5 个答案:

答案 0 :(得分:35)

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

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

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

您可以下载所有Intel 64 and IA-32 Architectures Software Developer's Manuals以开始使用。

答案 1 :(得分:22)

我在1977年开始编写程序集,采用漫长的路径:在为OS / 8和8k内存编写DEC PDP-8 / E程序之前,首先学习基本操作(和,或,xor,not)和八进制数学。这是在1977年。

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

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

为了学习汇编语言本身,我编写了一些简单的代码,看看编译器生成了什么,并在原始调试器中单步执行。我附近有说明书手册,所以我可以查看我不确定的说明。

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

那么什么是“原始调试器?”对我来说,它是一个调试器,是一个简单的开发包的一部分,并没有试图保护我免受可视调试器等硬件的影响。在其中我可以轻松地在源代码和汇编调试之间切换。它也可以从开发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的开发环境(也可能适用于服务器操作系统:s),它被称为Pelles C(pellesc.org)。它由瑞典的一位Pelle Orinius编写和维护,从我花了几个小时,我可以说它注定会成为我对x86-64的最爱。我已经尝试过Visual Express软件包(它们安装了很多垃圾 - 你知道之后你需要做多少卸载吗?超过20个)并且还尝试从一个地方获取gcc以使用IDE(eclipse或其他东西)来自另一个人。

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

我想我应该警告你,一旦掌握了它,你会注意到在附近的办公桌,咖啡机,会议,论坛以及许多其他地方会有人等着嘲笑你,取笑你,给你不完整的引用,并提供无知/无能的建议,因为你对集会感兴趣。为什么他们这样做我不知道。也许他们自己都是失败的汇编程序员,也许他们只知道OO(C ++,C#和Java),并且根本没有关于汇编程序的线索。也许他们“知道”(或他们的朋友知道的)“非常好”的人可能已经在论坛上阅读或在会议上听到了什么,因此可以提供关于为什么装配完全浪费的绝对真理时间。 stackoverflow中有很多这些。

答案 2 :(得分:3)

获取IDA pro.这是蜜蜂在组装工作时的膝盖。

我个人认为32位和64位之间没有太大区别。它不是关于位而是指令集。当你谈论汇编时,你谈论指令集。也许他们暗示32位指令集更好地学习。然而,如果这是你的目标,我建议唐纳德克努思的算法书籍 - 他们用7位指令集汇编教授算法:D

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

答案 3 :(得分:0)

  

但希望更好地了解较低级别的内容

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

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

答案 4 :(得分:0)

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

所以:学习汇编程序没有捷径。这可能很乏味。但是非常令人满意。