old*_*mer 23
我想每个人都给你相同的答案.指令集是处理器可以执行或理解的所有指令的集合(如数学中).汇编语言是一种编程语言.
让我根据你提出的一些问题尝试一些例子.而且无论我有什么代码,我都会从处理器跳到处理器.
指令或操作码或二进制或机器语言,无论您想要用于加载到处理器中要解码和执行的位/字节的术语.一个例子
0x5C0B
Run Code Online (Sandbox Code Playgroud)
汇编语言就是
add r12,r11
Run Code Online (Sandbox Code Playgroud)
对于这个特定的处理器 在这种情况下,这意味着r11 = r11 + r12.所以我把那个文本,在文本文件中添加r12,r11并使用汇编程序(编译/汇编汇编语言的程序)将它组装成某种形式的二进制文件.像任何编程语言一样,有时您创建目标文件然后将它们链接在一起,有时您可以直接使用二进制文件.并且有许多形式的二进制文件,它们是ascii和二进制形式,还有另外一个讨论.
现在你在汇编程序中可以做什么,而不是指令集的一部分?他们有什么不同?对初学者来说,你可以有宏:
.macro add3 arg1, arg2, arg3
add \arg1,\arg3
add \arg2,\arg3
.endm
.text
add3 r10,r11,r12
Run Code Online (Sandbox Code Playgroud)
宏就像内联函数,它们不是被调用的函数,而是生成代码.例如,与C宏没有什么不同.因此,您可以使用它们来保存一些打字,或者您可以使用它们来抽象您想要一遍又一遍地做的事情,并希望能够在一个地方进行更改而不必触及每个实例.上面的例子基本上生成了这个:
add r10,r12
add r11,r12
Run Code Online (Sandbox Code Playgroud)
指令集和汇编语言之间的另一个区别是伪指令,对于这个特定的指令集,例如,没有用于从堆栈中弹出东西的pop命令,至少不是通过该名称,我将解释原因.但是你可以保存一些打字并在你的代码中使用pop:
pop r12
Run Code Online (Sandbox Code Playgroud)
没有弹出的原因是因为寻址模式足够灵活,可以从源寄存器中读取地址,将值放在目标寄存器中,并通过一个字递增源寄存器.在这个指令集的汇编程序中
mov @r1+,r12
Run Code Online (Sandbox Code Playgroud)
pop和mov都会导致操作码0x413C.
指令集和汇编程序,切换指令集之间差异的另一个例子是这样的:
ldr r0,=bob
Run Code Online (Sandbox Code Playgroud)
对于这种汇编语言来说意味着将bob的地址加载到寄存器0中,没有指令,汇编程序用它做什么就会产生一些看起来像这样的东西,如果你用手写汇编程序:
ldr r0,ZZ123
...
ZZ123: .word bob
Run Code Online (Sandbox Code Playgroud)
本质上,在该指令的可到达位置,而不是在执行路径中,创建一个单词,链接器将使用bob的地址填充该单词.同样由汇编器或链接器的ldr指令将使用pc相对指令的ldr进行编码.
这导致指令集和汇编语言之间存在一整类差异
call fun
Run Code Online (Sandbox Code Playgroud)
机器代码无法知道什么是有趣的或在哪里找到它.对于具有多种寻址模式的指令集(注意我特意且有意避免命名我正在使用的指令集,因为这与讨论无关),汇编器或链接器视情况而定(取决于fun函数结束的位置)相对于这条指令).
汇编程序可以选择将该指令编码为pc relative,如果fun函数比调用指令提前40个字节,它可以用相当于call pc + 36的函数对其进行编码(因为pc在执行时是一条指令,所以需要四次关闭)这是一个4字节的指令).
或者汇编器可能不知道在哪里或什么是有趣的,并将其留给链接器,在这种情况下,链接器可以将函数的绝对地址设置为类似于调用#0xD00D.
对于加载和存储也是如此,一些指令集具有近和远的pc相对,一些具有绝对地址等.你可能不在乎选择,你可能只是说
mov bob,r1
Run Code Online (Sandbox Code Playgroud)
汇编程序或链接程序或两者的组合负责其余部分.
请注意,对于某些指令集,汇编程序和链接程序可能会在一个程序中同时发生.这些天我们习惯于编译对象然后链接对象的模型,但并非所有汇编程序都遵循该模型.
汇编语言可以采用一些快捷方式的更多情况:
hang: b hang
b .
b 2f
1:
b 1b
b 1f
1:
b 1b
2:
Run Code Online (Sandbox Code Playgroud)
hang:b hang很有意义,分支到名为hang的标签.本质上是自我的一个分支.顾名思义,这是一个无限循环.但对于这种汇编语言b.意味着分支到自我,一个无限循环,但我不必发明一个标签,键入它并分支到它.另一个捷径是使用数字b 1b意味着分支到1后面,汇编器在指令后面或上面查找标签号1.b 1f,它不是self的分支,意味着分支1向前,这是这个汇编程序的完全有效的代码.它将向前或低于标签编号1的代码行:并且您可以在汇编语言程序中为此汇编程序重复使用数字1疯狂,省去了为简单的短分支创建标签名称.第二个b 1b分支到第二个1.并且是自我的分支.
重要的是要了解创建处理器的公司定义了指令集,机器代码或操作码或它们或者您用于处理器解码和执行的位和字节的任何术语.通常,该公司将生成一个带有汇编语言的文档,用于这些指令,即语法.通常,该公司将生成一个汇编程序来编译/汇编该汇编语言......使用该语法.但这并不意味着地球上任何选择为该指令集编写汇编程序的人都必须使用该语法.x86指令集非常明显.同样,任何伪造的指令,如上面的弹出或宏语法或其他快捷方式,如b 1b,必须从一个汇编程序到另一个汇编程序.而且往往不是,你用ARM看到这个例如通用评论符号; 不适用于gnu汇编程序你必须使用@代替.ARM汇编程序确实使用了; (注意我用arm编写我的arm汇编程序; @使其可移植).使用gnu工具会变得更糟,例如你可以在汇编程序中使用#define和/*comment*/之类的C语言,并使用C编译器而不是汇编程序,它将起作用.我更喜欢尽可能保持最大的便携性,但自然你可以选择使用该工具提供的任何功能.