assembly 实现和语法的区别

kiz8lqtg  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(144)

经过大量的研究,我想我开始了解汇编程序是如何工作的
汇编器的工作原理就像编译器一样,它为预期的架构编译代码。而汇编语言是一种通用的思想,实现方式不同。但我不明白语法是如何工作的?不就是实现吗?
我已经搜索过了,但我找不到任何解释语法如何工作以及它与实现有何不同的东西。
我在http://sun.hasenbraten.de/vasm/How many assembly languages are there和更多的文章中看到过这个词的语法。
但我还是不明白。我发现的大多是AT&T语法和英特尔语法(有人能解释一下吗?)
这也是一个额外的问题:汇编程序是否可能支持多种体系结构?如果是,如何支持?

3z6pesqy

3z6pesqy1#

我觉得你想把事情弄得太复杂了。
因此,虽然许多人可以处理这个问题,并根据需要以这种方式编写和编程:

0xe0821003
0xe0021003
0xe0421003

字符串
只是写下来的比特。这是乏味的,增加了错误的几率。不容易阅读,所以不太维护。
因此,对于该指令集(伊萨)的这些位,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


作为一种汇编语言(我正在考虑的目标的机器代码实际上使它更容易编写/使用)。我们可以很容易地制作一个汇编器,它采用这种语法并创建与上面相同的机器代码。没有什么能阻止我们这样做。或者甚至将这样的语法添加到支持add r1,r2,r3的现有汇编器中,都可以由同一个工具支持。
重要的是机器码,我们不能简单地编造我们想要的任何比特,并让已经用一组规则实现的目标处理器改变这些规则(除非处理器被设计成像fpga那样做,但这不是我要说的)。
关于这一点有一个严重的误解,人们认为x86是唯一一个有不同语法的,每个目标都有一个语法。这里的故事是Intel vs AT&T,Intel定义并创建了支持这一点的工具:

mov ah,05h


对我们很多人来说,左边的目的地是很自然的,因为我们上过的每一门数学课都使用这个约定:

add r1,r2,r3
r1 = r2 + r3


但是那些为非DOS平台创建了一个不同的汇编程序的人,x86很快就进入了这个平台(其他一些操作系统,但一般都是嵌入式的)。

mov 05h,al


除了看起来很傻之外,这没有什么错:

add r2,r3,r1
r2 + r3 = r1


这是完全法律的,使任何语法你想要的,只要.你知道这一点.你建立正确的机器代码。
没有像一些高级编程语言那样的管理机构。充其量你有一个工具链问题,你有一个链接器,汇编器和编译器,编译器的输出通常是汇编语言,汇编器转换成对象,链接器转换成二进制文件,因此术语工具链。
编译器的输出和汇编器的输入必须达成一致,通常是一方规定,另一方遵守。因此,如果出于某种原因,你想在不同的后端滑动,那么你需要一个符合编译器输出的后端。你在汇编器和链接器之间有完全相同的情况,文件格式是完全任意的,无论作者选择发明什么,只要它能完成这项工作,但是对于一个工具来说,必须有一个商定的格式和/或另一个工具来从一种格式转换到另一种格式。
所以像gnu gcc这样的独立开发的编译器想要符合像gnu as这样的独立开发的汇编器,这将是最接近于一个管理机构来决定语言的规则,并且是开源的,个人可以随意添加一个功能到另一个中,并实现该功能的使用。
回到AT&T vs Intel;这被错误地认为是汇编语言差异的唯一案例。
尝试组装这个完美的法律的ARM代码

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


( Package 在某种对象文件格式中,这些位以该格式表示)
点是语言的每一个细微差别是相关的,一些标签必须在第一列开始,并有一个冒号,其他人没有。有些指令必须以点开始。GLOBAL和其他人没有GLOBAL,就在那里,代码是完全不兼容的,没有进入实际的指令。然后你有指令的差异。有一个非常糟糕的新时尚,不使用寄存器名称,我不能忍受,所以我可能做不好

add a0,v1,v2


这当然导致了完全的不相容,沿着的是这种疯狂:

mov %eax,0


几十年的成功解析器,你变得懒惰?
现在我们不知道你说的实现是什么意思。理想情况下,一个设计良好的汇编语言是一个你可以把汇编语言的“指令”Map到一个特定的机器指令。但不幸的是,我们有一些汇编语言是模糊的和/或指令集是模糊的。
例如,在一个虚构的指令集和汇编语言中,您可能支持

add r0,r1,#0
mov r0,r1

通常你会看到后者只是前者的伪代码,但我们在汇编语言和x86的指令集中都看到,有很多地方你可以用不止一种方式“实现”程序员的意图。
这就是你所说的执行吗?
更干净、更精简的指令集将保留指令集空间,而不是那些,例如,有些指令集可能没有nop,而工具可能只是使用

and r0,r0


但如果他们这么做了也就意味着

and r1,r1


相反,创建一个可以用不同方式实现的汇编语言指令。你也会看到伪指令。

push {r1}


这成为

stmia r13!,{r1}


因为指令集实际上没有push指令。
汇编已经发展到,曾经是十六进制数字,对于某些语言来说是12美元,英特尔喜欢这个12 h,但后来C变得流行和占主导地位,然后工具开始支持0x 12,所以你可以找到一个兼容的编译器家族,有一天他们不支持0x 12,下一个版本他们支持。
ARM在成为Acorn之后做了一些有趣的事情。他们创建了一个向后兼容32位的16位指令集,在他们的文档中,他们向您展示了完全兼容的32位指令,与较短的指令相同(显然只能单向)。
一种方法是大多数指令只支持一半的寄存器r 0-r7,而不是所有的r 0-r15,这意味着你只需要在指令中的三个比特,而不是四个。而arm有一些并不罕见,但也不常见的三个寄存器指令添加r1,r2,r3。很多旧的指令集,你可以做添加r1,不管语法是什么,这意味着一个操作数也是目的地,r1=r1+r2,他们对thumb中的一些指令也是这样做的,为什么这与这个讨论有关,因为对于早期的thumb汇编器来说,

add r1,r1,r2


后来,工具开始支持它,因为ARM的目标是这种统一的语法,这是愚蠢的,它使事情变得更糟而不是更好,但是不管怎样.所以有一天/版本,某个特定的汇编程序停止抱怨当用作thumb时的语法。
和更多的例外比规则手臂有两个现在三个(以及许多)指令集,让我们去与特定的拇指和特定的手臂和相同的语法,只要你留在一个子集的每一个可以用于不同的指令集(机器代码),如上所述

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 add r1,r1,r3 4:e0011003 and r1,r1,r3 8:e0411003 sub r1,r1,r3 c:18c9 adds r1,r1,r3 e:4019 ands r1,r3 10:1ac9 subs r1,r1,r3
现在有arm gnu的细微差别在这里发挥作用,继续沿着这个语法兔子洞的差异汇编语言之间的特定目标,不同的汇编器之间的目标(这不是x86)。
一般来说,尝试创建一个具有不同目标的指令集是没有意义的,除了上面提到的那些,你有一个从另一个指令集派生出来的指令集,并且在同一个内核中实现了一段时间。尝试创建一个语法,使x86或arm的机器代码只是改变目标,但使用相同的源代码。这没有意义,为什么要麻烦呢?关键是要生成机器码,你想要完全控制生成的特定指令,所以你需要目标特定的信息来实现。
如果你拉回并删除目标特定的细节,那么它就不再是汇编语言了,它是一种高级语言,如C或Python或Java或其他语言。这正是为什么我们有这些高级语言,这就是C在60年代来解决这个问题的原因,试图实现darpanet,但有不兼容的处理器被用来作为我们可能称之为调制解调器和/或者路由器的今天。由于世界是在快速处理器的发展,你必须不断重写相同的程序在汇编和/或需要创建高级语言,然后重新定位他们一旦你重新定位编译器,那么理想情况下,你可以重用一些百分比的“应用程序”的新目标。
现在有一些汇编语言,在某些圈子里很流行,它们是股票汇编的组合,让我制作我想要的机器代码,和一些更高级别的功能,以保存打字。
语法是如何工作的,你创造了一种语言来传达一种思想,如果我画一个盒子,上面有一个三角形,上面有另一个矩形,上面有一些弯曲的线,四分之一个圆,从纸的一角发出射线,两条垂直的线,上面有一些圆形的弯曲线,我们都同意(不管我们的母语是什么)那是一个角落里有太阳的房子,旁边有一棵树。

一个成功的语法是一个有意义和有用的,它并不比机器码本身更难。
实现就是简单地解析语法,然后生成机器码或数据,或者在第二次或以后的链接过程中使用标签来计算部分指令。这里再次强调,成功的语法是允许我们正确地描述我们希望工具生成的机器码的语法,功能上肯定,理想上具体。

相关问题