为什么我们需要汇编语言?


27

我们主要用高级语言编写程序。因此,在学习期间,我遇到了汇编语言。因此,汇编器将汇编语言转换为机器语言,而编译器对高级语言也是如此。我发现汇编语言有指令,如move r1 r3,move 5等等。这很难研究。那么为什么要创建汇编语言呢?还是比高级语言更先出现的汇编语言?为什么在我的计算机工程课上学习汇编程序?


13
汇编程序是人类可读的机器代码,这就是原因。
Andrej Bauer 2013年

4
因为重要的是要知道当我们接近硬件时事情是如何工作的。在编写汇编时,我们了解计算机硬件的工作原理和底层功能。最好的方法是汇编语言,因为机器语言是乏味的并且不像汇编那样可读。您是否真的想使用魔术盒而不看里面?
Spencer Wieczorek

Answers:


32

“那么为什么要创建汇编语言?”

汇编语言被创建为机器级编码的精确速记,因此您不必整天都计算0和1。它的工作方式与机器级代码相同:带有指令和操作数。

“谁先来?”

维基百科上有一篇很好的关于编程语言历史的文章

“为什么我要在计算机工程课上学习汇编程序?”

尽管这是事实,但您可能不会发现自己在汇编中编写下一个客户的应用程序,但是学习汇编仍然有很多好处。

如今,汇编语言主要用于直接硬件操纵,访问专用处理器指令或解决关键性能问题。典型用途是设备驱动程序,低级嵌入式系统和实时系统。

汇编语言与程序员一样接近于处理器,因此精心设计的算法非常出色-汇编对于速度优化非常有用。一切都与性能和效率有关。汇编语言使您可以完全控制系统资源。就像组装线一样,您编写代码以将单个值压入寄存器,直接处理内存地址以检索值或指针。(来源:codeproject.com


29

为什么我们需要汇编语言?

嗯,其实只有我们将永远一个语言需要,因而被称为“机器语言”或“机器代码”。看起来像这样:

0010000100100011

这是您的计算机可以直接说的唯一语言。它是CPU所使用的语言(从技术上讲,不同类型的CPU会使用不同的版本)。它也很烂地看着并试图理解。

幸运的是,二进制的每个部分都对应一个特定的含义。它分为多个部分:

0010|0001|0010|0011

operation type  source register  other source  destination register
0010            0001             0010          0011

这些值对应于:

operation type 0010 = addition
source register 0001 = register 1
other source 0010 = register 2
destination register 0011 = register 3

因此,此操作会将数字加到寄存器1和2中,并将该值放入寄存器3中。如果将这些值按字面意义放入CPU中并告诉它“执行”,它将为您添加两个数字。操作“减”可以是0011或类似的东西,而不是这里的0010。不管哪个值都会使CPU减去。

因此,程序可能看起来像这样(不要试图理解它,因为我编写了此特定版本的机器代码来解释问题):

instruction 1: 0010000100100011
instruction 2: 0011000110100100
instruction 3: 0101001100010111
instruction 4: 0010001001100000

这很烂吗?绝对是 但是我们需要用于CPU。好吧,如果每个机器代码都对应一个特定的动作,则只需简单地写一个“英文”简写,然后一旦我们了解了程序的功能,就将其转换为真正的二进制机器代码,并交给CPU运行。

因此,我们上面的原始指令可能如下所示:

(meaning)      operation type  source register  other source  destination register
(machine code) 0010            0001             0010          0011
("English")    add             r1               r2            r3

请注意,此英文版本具有与机器代码精确映射。因此,当我们编写一行“英语”时,实际上是在编写更友好,更易理解的机器代码。

好吧,这是汇编语言。这就是为什么它存在,以及它最初被创建的原因。

要了解我们为什么现在需要它,请阅读上面的答案,但是要理解的关键是:高级语言没有单一的表示形式是机器代码。例如,使用C,Python或其他任何方法:

z = x + y

这听起来像是我们从上方进行的加法运算,假设x位于寄存器1中,y位于寄存器2中,并且z应该以寄存器3结尾。

z = x * 2 + (y / 6) * p + q - r

尝试用16位二进制数表示行,并告诉CPU“运行”。你不能 机器代码没有一次执行加法,减法和其他任何操作的指令,一次执行4个或5个变量。因此,必须先将其转换为机器代码序列。这是您“编译”或“解释”高级语言时所做的。

好吧,我们有执行此操作的程序,那么为什么现在需要汇编?好吧,您的程序运行速度比预期的慢,并且您想知道原因。查看此行的机器语言“输出”,可能看起来像:

1010010010001001
0010001000010000
0110010000100100
0010001011000010
0010100001000001
0100010100000001
0010010101000100
0010101010100000
0000100111000010

只是为了完成那一行Python。所以你真的想调试吗?!?!?!NO。相反,您要求编译器以您实际上易于理解的形式为您提供输出,这是与该机器代码完全对应的汇编语言版本。然后,您可以确定编译器是否在做一些愚蠢的操作,然后尝试对其进行修复。

(有关@Raphael的建议的附加说明:实际上,您可以构造可与二进制代码以外的东西一起工作的CPU,例如三进制(基数3)或十进制代码,甚至是ASCII。不过,实际上,我们确实坚持使用二进制。)


2
原则上,没有什么可以阻止我们构建直接使用汇编语言的CPU。ASCII仅仅是用于此目的的低效率编码,仅此而已。
拉斐尔

感谢您的添加。我同意,但出于理解程序集的目的而略过了。我会加一个便条。
克里斯·库珀

15

那么为什么要创建汇编语言呢?还是在高级语言之前最先出现的语言?

是的,汇编是最早使用文本作为输入的编程语言之一,与使用焊线,使用插接板和/或翻转开关的文本不同。每种汇编语言仅针对一个处理器或一组处理器创建,因为指令直接映射到处理器运行的操作码

为什么在我的计算机工程课上学习汇编程序?

如果您需要对设备驱动程序进行编程或编写编译器,那么,如果不需要的话,了解处理器的工作原理非常重要。理解这一点的最好方法是在汇编中编写一些代码。

如果您看一下编译器如何编写代码,通常会看到调用约定的选项,而这些选项可能不了解汇编就无法理解。

如果您必须解决错误,并且唯一的输入是core dump,那么您肯定需要知道汇编才能理解输出,即汇编代码,并且如果幸运的话可以使用高级语言的高级语句进行扩充。


14

让我添加一个不太实际的方面。今天,这(可能)不是历史原因,而是您的原因。

汇编(与高级语言相比)是赤裸裸的。它不会隐藏任何东西(在软件中完成),从某种意义上讲它很简单,它具有相对较小的固定操作集。

这有助于进行精确的算法分析。语义和控制流非常简单,因此可以通过用过渡计数(概率)注释控制流图来对所有操作(或预期数量)进行计数。克努斯(Knuth)在他的TAoCP书籍中做到了这一点,取得了很大的成就,展示了其中一些最严格的算法分析。

轶事:我的同事已经学会了为此目的专门阅读Java字节码。


4

这里有答案:

所有这些答案都指向:

  • 速度/内存优化
  • 了解机器的工作方式
  • 因此,Noob程序员成为专家
  • 如果您知道汇编语言,就会知道如何为您的High Lvl语言编写编译器
  • 等等

1
您是否分享所有这些观点?你有什么经验?(特别是对我来说,“让Noob程序员成为专家”这个项目似乎已经过时了数十年。)
拉斐尔

哇,你不必在这个问题上变得如此敏感。我只是将答案链接到他重复的问题。而“让Noob程序员成为专家”在这里获得最高投票。去和他争论而不是我=)
compski

1
我不太敏感,我正在努力帮助您使答案成为一个很好的答案(由于您仅链接到一些资源,但没有一个资源能够完全回答问题),目前还不行。为此,第一步是要以比较的方式包括自己的想法。(请注意,通过以排他性方式关联观点,您可以为它们分配值;换句话说,您必须能够辩护为什么您认为观点足够重视,可以(重新)发表作为答案。)
拉斐尔

好吧,我的经验是,在习惯了一些高级编程语言之后,我真的非常讨厌学习汇编语言。而且我知道那些是优秀的程序员或事先了解C ++ / C的人都可以在ASM中很好地进行编程。我认为我的意见不足够有价值,无法在我的答案中发布,因此这就是为什么……
compski 2013年

您的第一个链接已损坏。
Hola Soy Edu Feliz Navidad

1

汇编=机器代码
有些人一直在争论汇编语言与CPU可以理解的数字代码有何不同。
这(虽然是真的)完全错了。
就翻译而言,汇编语言与数字(二进制​​,十六进制等)是一回事。

钩住它或放下它
如果您钩住装配,您就会知道实际计算机的工作方式。
组装程序涉及:

  • 学习说明及其含义(mean)。
  • 了解指令做什么,不做什么以及所有副作用
  • 了解CPU如何处理指令
    • 管道如何工作。
    • 什么multiscalar意思
    • 什么是CPU核心。
    • 缓存的工作方式。
    • 了解如何循环计数
    • 学习阿格纳雾的教s
  • 了解编译器如何生成代码以及它们有时如何失败。
  • 优化定义明确且非常具体的问题。

如果您组装组件,您几乎可以完全了解连接到键盘的CPU的工作原理。
您需要像脑外科医生使用手术刀一样使用这些知识。

不需要臭气熏天的抽象,
除非您笨拙地组装(以及因此在手术台上使用CPU),否则您将永远无法摆脱RAM机器的抽象离合器(或上帝禁止Turing机器恐怖)。

L33t Hax0r 5k1llz
组件还可以帮助您了解133thax0r如何设法击败保护方案。(问:为什么ASLR不起作用因为mov rax,fs:[28h]将其破坏了)。

0.1%
重要的不是组装知识,而是重要的机器知识。
如果您想了解机器,则必须了解它,这就是说机器的语言。

如果您不这样做,那么您将陷入抽象。
那是科学,那很好,但是那从来都不是全部。

这就像学习讲科萨语一样,
除非您追求大师级的水平,否则,最好还是坚持自己所知道的,这些点击会使您的生活变得复杂

因为很有趣。


1
在我所见过的文章中,最经常使用
grok一词

-1

到目前为止,我首先使用IBM System 32学习了RPG II,后来又在370上学习了APL。我全都在关注大小和速度。我的口头禅越来越小,越来越快。汇编是目前最紧凑,最快的语言。我将同时在C和Assembly中编写测试程序。在C程序需要100 Kb的情况下,等效的汇编程序通常会小于5 Kb。在研究C编译器的输出时,我会发现可以检查并重新检查参数的代码对可能的错误进行条件检查,这些错误通常很少发生,奇特而又不必要,所有这些都花费了时间,但是最大的内存膨胀是绝对传递了所有内容往返堆栈。

在当今的编程环境中,编写代码可提供更高级别的安全性和保护。能够直接从高级语言无法访问的硬件中读取信息,使您可以使用Assembly加密,使得程序只能在该特定机器上使用。例如,使用网络接口的MAC地址对用户密钥进行加密,然后将该密钥停放在硬盘驱动器的特定未注册扇区上,然后将该扇区标记为坏扇区,以使其他文件无法覆盖该扇区。当然,您失去了这个部门,那是什么?是数十亿还是万亿个字节中的2048个或4096个字节?


1
“高级语言无法访问”甚至意味着什么?
David Richerby
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.