我们主要用高级语言编写程序。因此,在学习期间,我遇到了汇编语言。因此,汇编器将汇编语言转换为机器语言,而编译器对高级语言也是如此。我发现汇编语言有指令,如move r1 r3,move 5等等。这很难研究。那么为什么要创建汇编语言呢?还是比高级语言更先出现的汇编语言?为什么在我的计算机工程课上学习汇编程序?
我们主要用高级语言编写程序。因此,在学习期间,我遇到了汇编语言。因此,汇编器将汇编语言转换为机器语言,而编译器对高级语言也是如此。我发现汇编语言有指令,如move r1 r3,move 5等等。这很难研究。那么为什么要创建汇编语言呢?还是比高级语言更先出现的汇编语言?为什么在我的计算机工程课上学习汇编程序?
Answers:
“那么为什么要创建汇编语言?”
汇编语言被创建为机器级编码的精确速记,因此您不必整天都计算0和1。它的工作方式与机器级代码相同:带有指令和操作数。
“谁先来?”
维基百科上有一篇很好的关于编程语言历史的文章
“为什么我要在计算机工程课上学习汇编程序?”
尽管这是事实,但您可能不会发现自己在汇编中编写下一个客户的应用程序,但是学习汇编仍然有很多好处。
如今,汇编语言主要用于直接硬件操纵,访问专用处理器指令或解决关键性能问题。典型用途是设备驱动程序,低级嵌入式系统和实时系统。
汇编语言与程序员一样接近于处理器,因此精心设计的算法非常出色-汇编对于速度优化非常有用。一切都与性能和效率有关。汇编语言使您可以完全控制系统资源。就像组装线一样,您编写代码以将单个值压入寄存器,直接处理内存地址以检索值或指针。(来源:codeproject.com)
为什么我们需要汇编语言?
嗯,其实只有我们将永远一个语言需要,因而被称为“机器语言”或“机器代码”。看起来像这样:
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。不过,实际上,我们确实坚持使用二进制。)
那么为什么要创建汇编语言呢?还是在高级语言之前最先出现的语言?
是的,汇编是最早使用文本作为输入的编程语言之一,与使用焊线,使用插接板和/或翻转开关的文本不同。每种汇编语言仅针对一个处理器或一组处理器创建,因为指令直接映射到处理器运行的操作码。
为什么在我的计算机工程课上学习汇编程序?
如果您需要对设备驱动程序进行编程或编写编译器,那么,如果不需要的话,了解处理器的工作原理非常重要。理解这一点的最好方法是在汇编中编写一些代码。
如果您看一下编译器如何编写代码,通常会看到调用约定的选项,而这些选项可能不了解汇编就无法理解。
如果您必须解决错误,并且唯一的输入是core dump,那么您肯定需要知道汇编才能理解输出,即汇编代码,并且如果幸运的话可以使用高级语言的高级语句进行扩充。
这里有答案:
为什么要学习汇编语言?加里·伯特(Gary L. Burt)
所有这些答案都指向:
汇编=机器代码
有些人一直在争论汇编语言与CPU可以理解的数字代码有何不同。
这(虽然是真的)完全错了。
就翻译而言,汇编语言与数字(二进制,十六进制等)是一回事。
钩住它或放下它
如果您钩住装配,您就会知道实际计算机的工作方式。
组装程序涉及:
multiscalar
意思 如果您组装组件,您几乎可以完全了解连接到键盘的CPU的工作原理。
您需要像脑外科医生使用手术刀一样使用这些知识。
不需要臭气熏天的抽象,
除非您笨拙地组装(以及因此在手术台上使用CPU),否则您将永远无法摆脱RAM机器的抽象离合器(或上帝禁止Turing机器恐怖)。
L33t Hax0r 5k1llz
组件还可以帮助您了解133thax0r如何设法击败保护方案。(问:为什么ASLR不起作用?因为mov rax,fs:[28h]
将其破坏了)。
0.1%
重要的不是组装知识,而是重要的机器知识。
如果您想了解机器,则必须了解它,这就是说机器的语言。
如果您不这样做,那么您将陷入抽象。
那是科学,那很好,但是那从来都不是全部。
这就像学习讲科萨语一样,
除非您追求大师级的水平,否则,最好还是坚持自己所知道的,这些点击会使您的生活变得复杂。
因为很有趣。
到目前为止,我首先使用IBM System 32学习了RPG II,后来又在370上学习了APL。我全都在关注大小和速度。我的口头禅越来越小,越来越快。汇编是目前最紧凑,最快的语言。我将同时在C和Assembly中编写测试程序。在C程序需要100 Kb的情况下,等效的汇编程序通常会小于5 Kb。在研究C编译器的输出时,我会发现可以检查并重新检查参数的代码对可能的错误进行条件检查,这些错误通常很少发生,奇特而又不必要,所有这些都花费了时间,但是最大的内存膨胀是绝对传递了所有内容往返堆栈。
在当今的编程环境中,编写代码可提供更高级别的安全性和保护。能够直接从高级语言无法访问的硬件中读取信息,使您可以使用Assembly加密,使得程序只能在该特定机器上使用。例如,使用网络接口的MAC地址对用户密钥进行加密,然后将该密钥停放在硬盘驱动器的特定未注册扇区上,然后将该扇区标记为坏扇区,以使其他文件无法覆盖该扇区。当然,您失去了这个部门,那是什么?是数十亿还是万亿个字节中的2048个或4096个字节?