我决定学习汇编语言,因为我开始知道学习它有很多好处,我们可以直接与硬件交互,我们可以学习计算机如何更好,等等。当我开始学习它时,我开始知道它有点奇怪而且不像其他编程语言所以我想也许我会发现它很难学。所以,我只是问一下学习汇编语言的基本先决条件是什么。有关信息,我已经学习了C,C ++,C#,PHP等编程语言。
答案 0 :(得分:7)
你必须告诉我们你想学习什么机器的装配。 ARM
,x86(_64)
,Sparc
等都是不同的ISA。
如果你只想介绍一般的汇编编程世界,Randal Hyde's Art of Assembly是一个很好的(虽然你写的不是汇编,而是高级和低级语言之间的混合,它会很好地向您介绍这个概念。
如果您已将目光投向x86
,我可以推荐这本书:Professional Assembly Language。除了那本书,sandpile.org是一个很好的资源。
对于x86
,环境的选择也很重要。 Here是伊利诺伊大学厄巴纳香槟分校ACM学生分会 - SIGWINDOWS的一个很棒的Windows程序集编程教程。对于Unix,我遇到的一个很棒的教程是this one。丹尼斯·尤里切夫(Dennis Yurichev)提供了一个更好,更一般的资源Reverse Engineering for Beginners。本书针对windows和unix环境,虽然它涉及逆向工程,但它可以帮助你学习很多关于计算机上运行的程序的阴谋。
对于ARM
,this article是一个很好的介绍。 This article is also another great introduction to the matter
答案 1 :(得分:3)
我在大约两个月前开始编写程序集,到目前为止它已经很顺利了。让我对迄今为止所学到的知识做一点总结。
<强>语法强>
x86汇编有两种主要的语法: Intel 和 AT&amp; T 。每个人都有利弊。 Intel语法似乎仅用于基于x86的处理器,而AT&amp; T语法用于几种不同的体系结构(例如ARM)。如果您查看OpenBLAS的源代码,您会发现它们使用AT&amp; T语法来表示几种不同的体系结构。但是,很多人认为英特尔语法更具可读性。到目前为止,我一直在使用英特尔语法进行编程,但我知道如何在大多数情况下阅读AT&amp; T语法。
<强>汇编强>
您可以使用GCC内联汇编,但不能使用MSVC 64位。到目前为止,我还没有对内联汇编感到困扰。您可以选择多个汇编程序,例如:MASM,NASM,YASM,FASM和GAS。 MASM仅使用英特尔语法,并且据我所知仅用于Windows(我不认为它可以是Linux的ELF目标文件)。 NASM也只使用英特尔语法,但可以创建几个不同的目标文件,例如适用于Windows和Linux。据我所知,YASM在很大程度上是NASM,但也支持AT&amp; T语法。 FASM使用Intel语法并且可以创建几个不同的目标文件,但它在几个方面与NASM和YASM有所不同。我还没有使用过FASM,但它看起来很诱人。 GAS使用AT&amp; T语法(虽然它可以使用Intel语法),实际上是用GCC编译时使用的语法。 GCC生产组件,发送给GAS。
了解每个汇编程序都有它的唯一方言非常重要,因此您不能期望用MASM编写的代码必须在NASM中开箱即用。据我所知,NASM和YASM在很大程度上是兼容的。
你应该选择哪个汇编程序?到目前为止我只使用过NASM。
调用约定并与C
链接到目前为止,我学习装配的最佳来源是GCC。用C编写代码然后查看程序集。例如,如果您有一个简单的函数foo
,则可以执行
gcc -O3 -S foo.c //AT&T syntax
gcc -O3 -S -masm=intel foo.c //Intel syntax
然后查看文件foo.s
,或者您可以使用objdump
gcc -O3 -c foo.c
objdump -d foo.o //AT&T syntax
objdump -d -Mintel foo.o //Intel syntax
您应该知道操作系统的function calling conventions。对于32位代码和64位代码,调用约定是不同的。对于Windows和Linux,它们对于32位代码是相同的,但对于64位代码则不同。到目前为止,我只用NASM for 64位编写了汇编代码。
关于SO的许多汇编问题似乎都是关于在汇编中编写整个函数,包括用户输入和输出。我不认为这是必要的。让C处理输入和输出。您可以看到this question的示例。我给出了NASM代码和C代码,并解释了如何组装,编译和链接它们。这是我在x86汇编中写的第一件事。在那个问题中我有一个功能
float triad(float *x, float *y, float *z, const int n);
Linux x86-64(或更确切地说是System V AMD64 ABI)调用约定传递rdi
寄存器中的第一个参数,rsi
中的第二个参数和rdx
中的第三个参数。所以在这种情况下rdi=x, rsi=y, rdx=n
。
一旦你获得了调用约定并且可以将程序集中的目标文件与C接口,你会发现使用程序集更容易。
最后,我学习装配的第二个最佳来源是Agner Fog's Optimizing Assembly manual。初学者手册的第一部分有很多好的建议。一旦你获得了一些经验,手册的后面部分就会有很多好的信息。
答案 2 :(得分:1)
计算机,汇编程序,描述所讨论汇编语言的书籍。既然你知道C,一些C编译器甚至允许你在C之间编写汇编。
答案 3 :(得分:1)
如果你选择正确的书,你真的不需要任何先决条件。
我自己学习汇编语言(基础,只是不需要更多)作为我的第一个编程语言(没有任何导师)Assembly Language Step-by-Step: Programming with Linux 3rd Edition。它教授基础知识,但阅读本书后,您可以毫无疑问地阅读任何其他高级装配书籍。
答案 4 :(得分:0)
汇编与您已经学过的任何高级语言不同。
一个好的起点是x86寄存器,这是我发现解释它们的网站:
http://www.eecg.toronto.edu/~amza/www.mindsec.com/files/x86regs.html
祝你好运!编辑:
同样,开始并坚持使用某种汇编语言总是好的,例如我从NASM开始,它有一个相当不错的社区,并且有一些很酷的功能,如符号管理和命名空间。