经过大量研究,我认为我开始学习汇编程序的工作原理
汇编器的工作原理类似于编译器,可为目标体系结构编译代码。 汇编语言是一个通用的概念,实现方式有所不同。 但是我不明白语法是如何工作的? 不仅仅是实现吗?
我进行了搜索,但找不到任何可以解释该语法如何工作以及与实现有何不同的内容。
我已经看到http://sun.hasenbraten.de/vasm/,How many assembly languages are there和更多文章中使用的语法这个词。
但是我还是不明白。大多数情况下,我发现AT&T语法和intel语法一样有用(有人可以解释吗?)。
这也是一个好问的问题:汇编程序是否可以支持多种体系结构?如果是,怎么做?
答案 0 :(得分:2)
我认为您正在尝试使这一过程变得过于复杂。
因此,尽管许多可以处理此问题,并根据需要以这种方式编写和编程:
0xe0821003
0xe0021003
0xe0421003
只需写下位。那是乏味的,并且会增加错误和错误几率。不容易阅读,因此不太容易维护。
因此,对于该指令集(ISA)的那些位,IP或处理器供应商创建了一种以人类可读/可写/可维护的方式传达意图的方式。
那将是
add r1,r2,r3
and r1,r2,r3
sub r1,r2,r3
但这是针对该特定目标的,并使用发明人提供的推荐语言。真正重要的是机器代码。我们中的任何人都可以创建一种汇编语言来使用此语言
bob b,c,d
ted b,c,d
joe b,c,d
会导致每种汇编语言使用相同的机器代码。我已经看到,创建并使用了支持此功能的工具
r1 = r2 + r3
r1 = r2 & r3
r1 = r2 - r3
作为一种汇编语言(我正在考虑的目标机器代码使之实际上更易于编写/使用)。我们可以很容易地制作出采用该语法并创建与上述相同的机器代码的汇编器。没有任何东西可以阻止我们这样做。甚至向支持添加r1,r2,r3的现有汇编程序添加类似的语法,都可能由同一工具支持。
重要的是机器代码,我们不能简单地组成所需的任何位,而已经用一组规则实现的目标处理器会更改这些规则(除非处理器被设计为像fpga那样做) ,但您知道那不是我在说的)。
对此有一个严重的误解,人们认为x86是唯一具有不同语法的脚本,而每个人每个目标都是一个语法。故事是intel vs AT&T,intel定义并创建了支持此功能的工具:
mov ah,05h
对于我们大多数人来说,目的地很自然,因为我们曾经参加过的每个数学课都使用该约定
add r1,r2,r3
r1 = r2 + r3
但是,人们为x86迅速迁移到的非DOS平台创建了一个不同的汇编器(某些其他操作系统,但通常是嵌入式的)。也许是因为他们喜欢最后有目的地,所以他们宁愿看到
mov 05h,al
除了傻傻的样子,这没什么不对的
add r2,r3,r1
r2 + r3 = r1
只要...知道这一点...构建正确的机器代码,就可以随意编写所需的语法,这是完全合法的。
没有像某些高级编程语言这样的管理机构。充其量您会遇到一个工具链问题,其中包含一个链接器,汇编器和编译器,编译器的输出通常是汇编语言,汇编器将其转换为对象,而链接器将其转换为二进制文件,因此称为工具链。
编译器的输出和汇编器的输入必须达成共识,通常一侧指示而另一侧遵从。因此,如果出于某种原因想要滑入另一个后端,则需要一个与copmiler输出一致的后端。您在汇编器和链接器之间的情况完全相同,只要作者选择执行此文件,文件格式就完全是任意的,但是对于一种工具,如果要移交给另一种工具,则必须有一种商定的格式和/或其他工具可以将格式从on转换为其他格式。
因此,像gnu gcc这样的单独开发的编译器要符合像gnu as这样的单独开发的汇编程序。那将是最接近决定语言规则的理事机构。作为开源人员,个人可以在其中添加一项功能,而在另一项中实现该功能的使用。
回到AT&T vs英特尔。这被错误地认为是汇编语言差异的唯一情况。
去尝试汇编这个完美的合法手臂代码
add r1,r2,r3 ; and r1,r2,r3
add r1,r2,r3 @ and r1,r2,r3
至少有一种工具很高兴,而另一种工具则不能走这条线
add r1,r2,r3 ; and r1,r2,r3
至少有一种工具可以提供
0xe0821003
0xe0021003
并且至少另一个将其作为输出
0xe0821003
(以某种目标文件格式包装,这些位以该格式表示)
要点在于语言的每一个细微差别都是相关的,有些标签必须从第一列开始并带有冒号,而其他标签则不需要。有些指令必须以点.GLOBAL开头,而有些指令则不要以GLOBAL开头,并且在那儿,代码完全不兼容,而无需进入实际的指令中。然后,您会有指令差异。不使用寄存器名称有一种非常糟糕的新风尚,我受不了了,所以我可能会把它们弄错了
add a0,v1,v2
这当然会导致完全不兼容以及这种精神错乱:
mov %eax,0
几十年的成功解析器,您会变得懒惰吗?
现在,我们不知道您所说的实现是什么意思。理想情况下,一种设计良好的汇编语言是一种您可以采用汇编语言“指令”并映射到特定机器指令的语言。但是不幸的是,我们有一些模糊的汇编语言和/或模糊的指令集。
例如,在我刚刚编写的指令集和汇编语言中,您可能支持
add r0,r1,#0
mov r0,r1
,由于某种原因,实际上为它们实施了不同的指令。通常,您会看到后者只是前者的伪代码,但是在汇编语言和x86指令集中我们都可以看到,在很多地方您可以通过多种方式“实现”程序员的意图。
您是在谈论实施吗?
更干净,更精简的指令集将保留指令集空间,但不保留指令集空间,例如,某些指令集可能没有nop,而某个工具可能仅使用
and r0,r0
尽管他们这样做就意味着他们也可以使用
and r1,r1
相反。创建一种可以以不同方式实现的汇编语言指令。您还将看到伪指令。
push {r1}
变成
stmia r13!,{r1}
因为指令集实际上没有推送指令。
汇编语言已经演变为,对于某些语言,十六进制数字以前是12美元,intel则喜欢12h,但是随后C变得流行和占主导地位,然后该工具开始支持0x12,因此可以找到其他兼容的编译器一家人,有一天他们不支持0x12,而他们支持的下一个版本。
ARM成为橡子后立即做出了一些有趣的事情。他们创建了一个向后兼容32位的16位指令集,在他们的文档中,他们向您展示了完全兼容的32位指令,它与较短的指令是相同的(显然只能采用一种方式)。
一种方法是大多数指令只支持寄存器r0-r7的一半,而不是全部r0-r15,这意味着指令中只需要3位,而不是4位。而arm有一些不常见但也不常见的东西,三个寄存器指令加了r1,r2,r3。许多旧的指令集都可以使用任何语法添加r1,r2,这意味着操作数也是目标r1 = r1 + r2。他们这样做是出于一些指导。为什么与本次讨论相关的是早期的拇指装配工
add r1,r1,r2
是非法的,即使在合法的情况下,您也会得到一个错误。然后后来这些工具开始支持它,因为理解了意图,并且因为arm的目标是这种统一的语法(这很愚蠢),所以会使情况变得更糟而不是更好,但是无论如何……所以有一天一个特殊的汇编器在用作拇指时不再抱怨该语法。
除了规则臂之外,还有更多的例外情况,即现在有两个(三个)指令集,只要您留在每个子集的子集中,就可以使用特定的拇指和特定的臂以及相同的语法如上所述的不同指令集(机器代码)
add r1,r1,r3
and r1,r1,r3
sub r1,r1,r3
.thumb
add r1,r1,r3
and r1,r1,r3
sub r1,r1,r3
给予
0:e0811003加r1,r1,r3 4:e0011003和r1,r1,r3 8:e0411003子r1,r1,r3 c:18c9加r1,r1,r3 e:4019 ands r1,r3 10:1ac9子r1,r1,r3
现在这里正在发挥作用的细微差别,使特定目标的汇编语言之间的语法漏洞逐渐消失,该目标的汇编语言之间的差异也不同(不是x86)。
通常,尝试创建具有不同目标的指令集毫无意义,除了上述情况外,您有一个源于另一目标的指令集,该指令集是在另一时间一次或一段时间内实现的。相同的核心。尝试使一种语法成为x86或arm的机器代码,只是更改了目标,但使用了相同的源代码。那没有意义,为什么要打扰。关键是制作机器代码,即您要完全控制生成的特定指令。因此,您需要目标特定的信息才能做到这一点。如果撤回并删除目标特定细节,则它不再是汇编语言,而是C或python或JAVA或其他高级语言。这就是为什么我们要使用那些高级语言来解决这个确切的问题,这些语言是60年代C来的,试图实现darpanet,但现在使用不兼容的处理器来称呼我们今天的调制解调器和/或路由器。 。由于当今世界处在快速的处理器发展阶段,因此您必须继续用汇编语言重新编写相同的程序,并且/或者需要创建高级语言,然后在重新定向编译器之后重新定向它们,那么理想情况下,您可以重用一定比例的“应用”上的新目标。
现在,有一些汇编语言在某些圈子中很流行,这些语言是股票汇编的组合,使我可以制作所需的机器代码,还可以使用一些更高级的功能来节省输入。
语法的工作原理是创建一种可以传达思想或思想的语言。如果我画一个盒子,上面有一个三角形,另一个矩形,在那个四分之一圆的顶部有一条曲折的线,光线从纸的角出来,有两条垂直线,上面有一些圆形的花线,那么我们都同意我们的母语是那是一栋房子,在角落里有阳光,旁边是一棵树。
成功语法是一种有意义且有用的语法,它不比机器代码本身难。
实现只是简单地解析该语法并生成机器代码或数据,或者使用标签在链接的第二遍或更高版本中计算指令的一部分。再次,一种成功的语法是一种语法,它使我们能够正确地,理想地,理想地描述我们希望该工具生成的机器代码。