14

我做了一些搜索,但找不到明确的答案,所以我希望我能得到你的意见。

我想学习汇编语言 (ARM) - Raspberry Pi 会是一个不错的选择吗?

从我所见,似乎有一些温和的教程可以做一些事情,比如制作 LED 闪光灯等,所以从新手的角度来看,它并不太可怕,而且实际上看起来很有趣。

如果我从 Raspberry Pi 开始,然后转而使用反汇编程序来积累我的知识,那么我是走在了正确的道路上,还是开始走错了路?

谢谢您的意见。

4

1 回答 1

22

是和不是。如果这是您的第一个汇编语言,那么 ARM 是一个很好的开始(x86 是一个坏的)(还有其他好的)。我建议首先使用指令集模拟器学习。这可以让您更好地了解正在发生的事情,并为您提供更好的成功机会(减少因挫折而放弃的机会)。一旦你用工具弄湿了你的脚,构建裸机程序等,那么树莓派就不是一个糟糕的平台。外围设备虽然文档很少,但使用起来非常简单(与其他类似平台相比),有足够的社区和示例来弥补文档的不足。从 ARM 的角度来看,树莓派可以被认为是不可变砖的。尝试制作您的第一个闪烁的 LED 程序可能会非常令人沮丧。

我非常相信编写反汇编程序作为学习新(对我而言)指令集的一种方式。ARM 指令集是固定字长(32 位),非常容易反汇编。纯拇指指令固定为16位,更容易反汇编。thumb 有 thumb2 扩展,这使得它更难,所以我一开始会避免这些。使用固定字长指令集,您可以安全地浏览二进制图像并从头到尾进行反汇编。数据看起来很奇怪,但说明会在正确的位置。使用可变字长,您不能简单地从头开始并线性反汇编(使用 thumb2 扩展意味着可变指令长度),您可能有一个三字节指令,然后是一个字节数据,然后是另一个指令字节,线性地,该字节数据将被反汇编为指令,如果它碰巧解码为多字节指令,那么现在您不同步了。反汇编可变指令长度二进制文件的唯一正确方法是按照执行顺序跟踪代码的所有路径,并从该反汇编中尽可能地反汇编(如果不模拟所有可能的代码路径,您可能无法将所有指令与数据区分开来) . 可变指令长度反汇编绝对是一个高级主题,首先要掌握一些汇编语言的力量。甚至可能在处理反汇编程序之前为可变字长指令集创建一个指令集模拟器(基本上,无论如何,您必须通过二进制文件解码,不是完全解码而是部分解码,以便为可变字长指令集制作反汇编程序。

thumbulator 和 amber_samples 方法都是固定指令长度,因此很容易看到 asm 到机器代码到 asm 的关系。以及查看您的代码运行并了解它为什么会进入杂草并死亡(您不会在树莓派或任何其他硬件上看到)。

有一个 cambride 大学示例通过简单的闪烁 LED 示例握住您的手,然后进入视频像素。以及在讨论论坛的裸机部分发布了指向其示例的链接的其他人。为了了解“我如何在汇编语言中做到这一点”,编写小的 C 函数,编译(优化)然后反汇编。我专门讨论的是 a + b 之类的代码,而不是 printf() 之类的代码。学习汇编语言,指令集,它是处理器家族特有的(通用的)。那么我会在学习系统调用或库调用之后争论。“我如何打印字符串”之类的东西涉及硬件学习,系统(ROM 监视器/调试器)或库(C 库或其他高级语言函数调用和约定以利用它们的库,这些库本身可能会调用许多其他库,从而导致大量垃圾链接)。所以使用 C 来学习“汇编语言”意味着没有库调用,没有 memcpy 没有 printf 等。不过,如果你使用系统和库调用,那么你必须编写 asm 代码才能在该系统或链接上运行与那些本身可能具有系统依赖性的调用。考虑学习高级语言 C 或 Python 等。学习语言、声明变量、学习加法、减法、异或等运算符。如何使用指针和数组等。在某些时候你会学习 C 库调用、printf()、strcpy()、malloc 等 YMMV,

如果您选择学习 asm 作为系统的一部分,那么我建议您留在 linux 中,创建一些简单的 C 函数,编译和反汇编,学习编译器的调用约定并使用 arm 参考资料查找说明,如您所见它们由编译器创建。学习使用 asm 从头开始​​创建该函数并将其与 C 程序链接,然后修改该函数。这是与我上面描述的完全不同的方法。有失败的可能性,但绝对是一种通过示例学习的方法。

于 2012-12-01T18:49:56.907 回答