有哪些在线学习汇编代码的好课程。我看过一些课程,但它们都使用 .asm 文件进行教学。我正在尝试学习文件扩展名为 .s 的程序集
这两种汇编文件之间的主要区别是什么?这个比那个好吗?
我也听说过很多“ARM”、“x86”和“x86-64”。它们到底是什么?我想学习的是“ARM”。
提前致谢!
X86(32 位)和 X86-64(64 位)是典型 PC 中使用的处理器。
ARM 处理器通常用于嵌入式设备、电话、硬盘驱动器……。如果您想对 ARM 处理器进行编程,则需要某种基于 ARM 的开发板 | 系统和软件工具。ARM 处理器有多种变体,指令集有所不同。如果您打算获得一个开发系统,我不确定要推荐哪种 ARM 处理器。
汇编语言特定于汇编器(工具)而不是目标(处理器)。有许多不兼容的 x86 汇编器和汇编语言,以及许多 ARM 汇编器和汇编语言。
x86 意味着几十年来英特尔 8088/86 及其衍生产品的特定指令集。mov al,10h 等指令。指令集已经扩展并且是反向兼容的。AMD 和过去一小部分制造 x86 兼容/许可处理器意味着它们运行相同的指令,但芯片不是由英特尔制造的。
ARM 描述了在 ARM 处理器上运行的指令集的简短列表,从制造芯片的 Acorn 开始,到仅制造 IP 而不是芯片的后橡子。对于每个 x86 处理器/内核,您的生活中都会有几到几到多个基于 ARM 的项目(以及其他处理器)。ARM 不是一个糟糕的第一个指令集,gnu 汇编器和 gnu 工具是一个很好的起点(binutils)。
文件名不相关,有些工具有默认值,有些则不关心(例如,如果您将 .s 或 .S 提供给 gnu gcc,它知道这不是 C 文件)。文件扩展名通常没有意义。通常,您将整个文件名提供给工具,因此,例如,在您使用错误工具 (gcc) 的情况下,它可能会帮助工具解决问题,但对于真正的汇编器来说,这将取决于汇编器本身关心。但扩展名并不表示 x86 vs ARM vs MIPS 等...
ARM 有多个指令集,ARM 从架构 v1 到 v3(橡子时代)然后 ARM v4 到 ARMv7 是 v3 到 v4 的扩展,删除了一些否则它是添加的。ARMv4 到 ARMv7 也有各种版本的 thumb 指令,其中指令是 32 位 thumb 指令是基于 16 位的。然后是 Jazelle 和多个浮点指令集。然后是 64 位指令集,这完全是另一回事。最好从模拟器或微控制器上的拇指开始,然后升级到 ARM。你可以在一个周末为 thumb 制作一个指令集模拟器,并且比大多数经常使用它的人更好地学习指令集。
指令集就是一组指令。一种型号/品牌的咖啡机可能有一个拨动开关来打开它。另一个按钮。另一个你只需插入或拔出它。他们都对该咖啡机执行开/关指令,但如何执行该操作的具体细节各不相同。
指令是位,处理器非常愚蠢,程序员的聪明才智都在按顺序排列指令列表的程序员身上,即使被告知崩溃和烧毁,处理器也会执行它被告知的事情。因此,虽然 x86、ARM、MIPS 等都有寄存器并且寄存器可以保存值 123、寄存器的名称、将 123 放入特定寄存器的指令、告诉处理器执行该操作的特定位模式,因指令集而异。然后除此之外,不必输入二进制或十六进制来编写人类更喜欢使用人类可读的程序的程序。
而不是编写这样的程序
0xe3a0007b
我们可以改用这个:
mov r0,#123
但是由于汇编程序(工具)作者的历史和偏好,可以从不同的汇编语言创建相同的指令,即相同的机器代码。找到这些样式并不少见(并不是说该指令集有人为这些样式制作工具)
mov r0,123
mov 123,r0
mov #123,r0
mov r0,123d
mov r0,$123
load banana,123
所以:
mov r0,#0x99
0: e3a00099 mov r0, #153 ; 0x99
mov r0,#0x99
0: 2099 movs r0, #153 ; 0x99
li $2,0x99
0: 24020099 li $2,153
mov al,99h
b0 99
mov $0x99,%al
0: b0 99 mov $0x99,%al
addi x1,x0,0x99
0: 09900093 addi x1,x0,153
movb $0x99,r0
0: 95c0 0099 movb $231, r0
这些是各种汇编语言和指令集。它们都执行相同的基本功能,将值 0x99 放入处理器寄存器之一。正如您所看到的,机器代码、位和语法因汇编器和目标而异。一个特定的处理器可能只支持一个或几个指令集,如果处理器支持多个指令集,您必须将机器代码与处理器匹配并为该机器代码配置处理器。
每个指令集都有指令,理想情况下有一个或多个汇编器,这意味着一种或多种汇编语言。一旦你学习了一个指令集,下一个和下一个就容易多了。一些指令集不是最好的开始,较新的 ARM 和 X86 和其他指令集有大量与保护相关的逻辑,除了指令集本身可能会阻碍学习基础知识。因此,较旧或更简单的指令集作为第一个指令集更好。有些规则比其他规则更多,正交性更小。pdp11 和 msp430 是非常好的第一个指令集,有模拟器,你可以在一个下午自己搞定。
您可以购买一个 msp430,而 pdp11 可以运行一个并不一定微不足道也不便宜。Thumb 是一个好的开始,有模拟器和便宜的硬件,从 thumb 到 ARM 的跳转相当简单。他们的文档很好。许多人会争辩说他们最喜欢的或者他们知道的唯一一个是最好的第一个。在你尝试之前你不会知道,但我建议你不要停留在一个。gnu 工具(binutils 和 gcc)支持许多不同的指令集,并且这些工具经过调试,因此您可以将工具输出与该处理器的文档进行比较,并找出发生了什么......
unsigned char fun ( void )
{
return(0x99);
}
00000000 <fun>:
0: e3a00099 mov r0, #153 ; 0x99
4: e12fff1e bx lr
00000000 <fun>:
0: 2099 movs r0, #153 ; 0x99
2: 4770 bx lr
00000000 <_fun>:
0: 95c0 ff99 movb $-147, r0
4: 0087 rts pc
00000000 <fun>:
0: 09900513 addi x10,x0,153
4: 8082 c.jr x1
00000000 <fun>:
0: 7f 40 99 ff mov.b #-103, r15 ;#0xff99
4: 30 41 ret
00000000 <fun>:
0: e820 jr $31
2: 6a99 li $2,153
00000000 <fun>:
0: 03e00008 jr $31
4: 24020099 li $2,153