汇编语言lsl是什么意思(汇编语言LSL是什么指令)

OK01课程讲解了如何入门树莓Pi,以及如何在树莓Pi上启用RCA和USB端口附近的OK或ACT LED灯。这个指示灯本来是用来指示OK状态的,但是在树莓派第二

汇编语言lsl是什么意思(汇编语言LSL是什么指令)

OK01课程讲解了如何入门树莓Pi,以及如何在树莓Pi上启用RCA和USB端口附近的OK或ACT LED灯。这个指示灯本来是用来指示OK状态的,但是在树莓派第二版上改名为ACT。

1、入门

让我们假设您已经访问了下载页面,并且已经获得了必要的GNU工具链。还下载了一个叫操作系统模板的文件。请下载该文件,并将其解压缩到一个新目录中。

2、开始

现在,您已经扩展了这个模板文件,并在源目录中创建了一个名为main.s的文件。这个文件包含这个操作系统的代码。具体来说,该文件夹的结构应该如下所示:

构建/

(空的)

来源/

主菜单

内核. ld

许可证

生成文件

用文本编辑器打开main.s文件,这样我们就可以输入汇编代码。Raspberry Pi使用了一种叫做ARMv6的汇编代码变体,这就是我们将要编写的汇编代码类型。

扩展名为的文件。s一般是汇编代码。要记住这里是ARMv6的汇编代码。

首先,我们复制以下命令。

。部分。初始化

。全球_开始

_start:

实际上,上面的指令并没有在Raspberry Pi上做什么,它们是提供给汇编程序的。Assembler是一个转换程序,把我们能理解的汇编代码转换成树莓派能理解的机器码。在汇编代码中,每一行都是一个新命令。上面的第一行告诉汇编器1把我们的代码放在哪里。我们之所以把它放在一个名为。提供的模板中的init是输出的起点。这很重要,因为我们想确保我们可以控制哪个代码先运行。如果不这样做,运行的第一个代码将是按字母顺序排列的第一个代码!的。section命令只是告诉汇编程序将代码放在哪个节中,从这一点开始直到下一点结束。节或文件。

在汇编代码中,可以跳过一些行,并在命令之前或之后放置空以提高可读性。

接下来的两行是停止警告消息。它们并不重要。2

3、第一行代码

现在,我们正式开始写代码。当计算机执行汇编代码时,它只是按顺序一行一行地执行每条指令,除非它被明确地告知不是这样。每条指令从新一行开始。

复制以下命令。

ldr r0,=0x20200000

Ldreg,= val将数值val加载到寄存器reg中。

那是我们的第一份订单。它告诉处理器将数字0x20200000保存到寄存器r0中。这里我需要回答两个问题。什么是语域?0x20200000是一个什么样的数字?

在寄存器处理器中,它是一个非常小的内存块,是处理器保存正在处理的数的地方。处理器中有许多寄存器,其中许多都有特殊用途。我们以后会一个一个的去接触。最重要的有十三个(命名为r0,r1,r2,…,r9,r10,r11,r12)。它们被称为通用寄存器,您可以使用它们进行任何计算。因为我们编写了第一行代码,所以在示例中使用了r0。当然,你可以使用其中任何一个。只要后面一致,就不会有问题。

Raspberry Pi上的单个寄存器可以保存0到4,294,967,295(含)之间的任何整数。它可能看起来像一个大内存,但实际上它只有32个二进制位。

0x20200000确实是个数字。只不过它是用十六进制表示的。

因此,我们编写的第一个汇编命令是将数字2020000016装入寄存器r0。那个顺序看似无用,其实不然。在计算机中,有许多内存块和设备。为了能够访问它们,我们给每个内存块和设备分配了一个地址。就像邮政地址或网站地址一样,用来标识我们要访问的内存块或设备的位置。电脑中的地址是一串数字,所以上面的数字2020000016就是GPIO控制器的地址。这个地址是厂家设计决定的,他们也可以用其他地址(只要不跟别人冲突)。我知道这个地址是GPIO控制器的地址是因为我看了它的说明书,3地址的使用没有特别的规范(除了都是十六进制的大数)。

4、启用输出

显示GPIO控制器关键部件的图表。

看完手册,我们知道需要给GPIO控制器发送两条消息。我们必须用它的语言告诉它,如果我们这样做,它会很高兴实现我们打开OK LED指示灯的意图。幸运的是,它是一个非常简单的芯片。为了让它明白我们要做什么,我们只需要为它设置几个数字。

1号mov r1

lsl r1,#18

字符串r1,[r0,#4]

MOV,# val将数值val放入名为reg的寄存器中。

Lsreg,# val将寄存器reg中的二进制操作数左移val位。

Str reg,[dest,#val]将寄存器reg中的数字保存到地址dest+val。

这些命令的目的是启用GPIO引脚16上的输出。首先,我们在寄存器r1中获取一个必要的值,然后将该值发送给GPIO控制器。因此,前两个命令试图将值存入寄存器r1。我们可以像以前一样使用另一个命令ldr,但是lsl命令对我们以后能够设置任何给定的GPIO引脚更有用,因此从公式中导出值比直接写出来更好。指示OK的LED直接连接到GPIO的管脚16,所以我们需要发送一个命令来启用管脚16。

使能LED引脚需要r1寄存器中的值。第一行命令将数字110放在r 1中。在这种操作中,mov命令比ldr命令快得多,因为它不需要与存储器交互,而ldr命令将所需值从存储器载入寄存器。但是,mov命令只能用于加载一些值。4在ARM汇编代码中,基本上每条指令都用一个三个字母的代码来表示。它们被称为助记符,用于表示操作的目的。Mov是“move”的简称,ldr是“load register”的简称。Mov将第二个参数#1移至之前的r1寄存器。一般来说,#肯定是一个数的意思,但是我们见过一个不符合这种情况的反例。

第二条指令是lsl(逻辑左移)。它意味着将第一个参数的二进制操作数向左移动第二个参数表示的位数。在这种情况下,将110(即12)向左移动18位(使其为1000000000000002 = 26214410)。

还是那句话,只有看手册才能知道自己需要的数值。根据手册,GPIO控制器中有一组24字节,决定GPIO引脚的设置。前4个字节与前10个GPIO引脚相关,后4个字节与接下来的10个引脚相关,依此类推。总共有54个GPIO管脚,所以我们需要一组6×4字节,总共是24字节。在每4个字节中,每3位与一个特定的GPIO引脚相关。我们要使能的是第16个GPIO管脚,所以需要设置第二组4个字节,因为第二组4个字节是用来处理第10-19个GPIO管脚的,而我们需要的是第六组3位,上面代码中的个数是18(6×3)。

最后一个str(“store register”)命令保存第一个参数中的值,并将寄存器r1中的值保存到由以下表达式计算的地址。这个表达式可以是一个寄存器,在上例中是r0。我们知道GPIO控制器的地址保存在r0中,另外一个值加进去,在这个例子中是#4。这意味着在GPIO控制器的地址上加4得到一个新地址,并将寄存器r1中的值写入该地址。该地址是前面提到的第二组4字节的位置。因此,我们向GPIO控制器发送第一条消息,告诉它准备启用GPIO第16个引脚的输出。

5、生命的信号

现在LED已经可以打开了,我们还需要实际打开它。这意味着需要向GPIO控制器发送一条消息来关闭引脚16。是的,你没看错,就是你想发出一个关闭的信息。芯片厂商认为,在GPIO引脚关闭的情况下打开LED更有意义。硬件工程师经常做出这种违反直觉的决定,似乎是为了让操作系统开发者保持警惕。就当是对自己的警告吧。

1号mov r1

lsl r1,#16

字符串r1,[r0,#40]

我希望你能知道上面所有的命令,不管它们的值是多少。和以前一样,第一个命令是将值1推入寄存器r1。第二个命令是将二进制1向左移位16位。由于我们要关闭GPIO的第16脚,所以需要在下一条消息中设置第16位为1(要设置其他脚,只需要改变相应的位)。最后,我们将这个值写入GPIO控制器的地址加4010,这将使该引脚关闭(加28将打开该引脚)。

6、永远幸福快乐

现在好像可以结束了,可惜处理器不知道我们做了什么。事实上,处理器只要通电,就永远不会停止运行。因此,我们需要给它一个任务来保持它的运行,否则,Raspberry Pi会进入睡眠状态(不是在这个例子中,LED灯会一直亮着)。

循环美元:

b循环$

名称:下一行的名称。

标签的下一行将在标签处运行。

第一行不是命令,而是标签。它将下一行命名为loop$,这意味着我们可以通过名称指向该行。这叫做标签。当代码转换成二进制时,标签会被丢弃,但我们用名字而不是数字(地址)来找行更有用。传统上,我们用一个$表示这个标签只对这个代码块中的代码起作用,这样别人就可以知道它对整个程序不起作用。b(“branch”)命令将运行指定标签中的命令,而不是它后面的下一个命令。因此,下一行将再次运行这个b命令,这将导致无限循环。因此,处理器将进入无限循环,直到安全关闭。

代码块末尾的空行是有意这样写的。GNU工具链要求所有汇编代码文件都以空行结束,所以你真的想结束也没关系,文件不会被截断。如果你不这样做,当汇编程序运行时,你会收到一个恼人的警告。

7、树莓派上场

由于我们已经写完了代码,现在,我们可以将它上传到树莓派中了。在你的计算机上打开一个终端,改变当前工作目录为 source 文件夹的父级目录。输入 make 然后回车。如果报错,请参考排错章节。如果没有报错,你将生成三个文件。 kernel.img 是你的编译后的操作系统镜像。kernel.list 是你写的汇编代码的一个清单,它实际上是生成的。这在将来检查程序是否正确时非常有用。kernel.map 文件包含所有标签结束位置的一个映射,这对于跟踪值非常有用。现在我们已经写好了代码,可以上传到Raspberry Pi了。打开计算机上的终端,将当前工作目录更改为源文件夹的父目录。输入make并输入。如果您报告了错误,请参考故障排除章节。如果没有错误,您将生成三个文件。Kernel.img是您编译的操作系统映像。Kernel.list是你写的汇编代码的列表,实际生成的。这在以后检查程序是否正确时非常有用。kernel.map文件包含所有标签的结束位置的映射,这对于跟踪值非常有用。

为安装你的操作系统,需要先有一个已经安装了树莓派操作系统的 SD 卡。如果你浏览 SD 卡中的文件,你应该能看到一个名为 kernel.img 的文件。将这个文件重命名为其它名字,比如 kernel_linux.img。然后,复制你编译的 kernel.img 文件到 SD 卡中原来的位置,这将用你的操作系统镜像文件替换现在的树莓派操作系统镜像。想切换回来时,只需要简单地删除你自己的 kernel.img 文件,然后将前面重命名的文件改回 kernel.img 即可。我发现,保留一个原始的树莓派操作系统的备份是非常有用的,万一你要用到它呢。要安装您的操作系统,您需要一个安装了Raspberry Pi操作系统的SD卡。如果您浏览SD卡中的文件,您应该能够看到一个名为kernel.img的文件。将该文件重命名为另一个名称,如kernel_linux.img。然后,将您编译的kernel.img文件复制到SD卡中的原始位置,这将使用您的操作系统映像文件替换当前的Raspberry Pi操作系统映像。当你想切换回来的时候,只需删除自己的kernel.img文件,然后把之前重命名的文件改回kernel.img,我发现保留一份原树莓Pi操作系统的备份,以备不时之需,非常有用。

将此SD卡插入树莓派,打开电源。该OK LED将会亮起。如果不是这样,请查看故障排除页面。如果一切顺利,恭喜你,你已经写出了你的第一个操作系统。课程OK02将指导您打开和关闭LED灯。

是的,我说错了,它告诉的是链接器,它是另一个程序,用于将汇编器转换过的几个代码文件链接到一起。直接说是汇编器也没有大问题。 ↩其实它们对你很重要。由于 GNU 工具链主要用于开发操作系统,它要求入口点必须是名为 _start 的地方。由于我们是开发一个操作系统,无论什么时候,它总是从 _start 开时的,而我们可以使用 .section .init 命令去设置它。因此,如果我们没有告诉它入口点在哪里,就会使工具链困惑而产生警告消息。所以,我们先定义一个名为 _start 的符号,它是所有人可见的(全局的),紧接着在下一行生成符号 _start 的地址。我们很快就讲到这个地址了。 ↩本教程的设计减少了你阅读树莓派开发手册的难度,但是,如果你必须要阅读它,你可以在这里 SoC-Peripherals.pdf 找到它。由于添加了混淆,手册中 GPIO 使用了不同的地址系统。我们的操作系统中的地址 0x20200000 对应到手册中是 0x7E200000。 ↩mov 能够加载的值只有前 8 位是 1 的二进制表示的值。换句话说就是一个 0 后面紧跟着 8 个 1 或 0。 ↩一个很友好的硬件工程师是这样向我解释这个问题的: ↩原因是现在的芯片都是用一种称为 CMOS 的技术来制成的,它是互补金属氧化物半导体的简称。互补的意思是每个信号都连接到两个晶体管上,一个是使用 N 型半导体的材料制成,它用于将电压拉低,而另一个使用 P 型半导体材料制成,它用于将电压升高。在任何时刻,仅有一个半导体是打开的,否则将会短路。P 型材料的导电性能不如 N 型材料。这意味着三倍大的 P 型半导体材料才能提供与 N 型半导体材料相同的电流。这就是为什么 LED 总是通过降低为低电压来打开它,因为 N 型半导体拉低电压比 P 型半导体拉高电压的性能更强。还有一个原因。早在上世纪七十年代,芯片完全是由 N 型材料制成的(NMOS),P 型材料部分使用了一个电阻来代替。这意味着当信号为低电压时,即便它什么事都没有做,芯片仍然在消耗能量(并发热)。你的电话装在口袋里什么事都不做,它仍然会发热并消耗你的电池电量,这不是好的设计。因此,信号设计成 “活动时低”,而不活动时为高电压,这样就不会消耗能源了。虽然我们现在已经不使用 NMOS 了,但由于 N 型材料的低电压信号比 P 型材料的高电压信号要快,所以仍然使用了这种设计。通常在一个 “活动时低” 信号名字上方会有一个条型标记,或者写作 SIGNAL_n 或 /SIGNAL。但是即便这样,仍然很让人困惑,那怕是硬件工程师,也不可避免这种困惑!

via:https://www . cl . cam . AC . uk/projects/raspberrypi/tutorials/OS/ok01 . html

作者:罗伯特·穆林斯题目:lujun9972译者:qhwdw校对:wxy

本文由LCTT原创,Linux中国隆重推出。

点击“了解更多”可访问文内链接

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。

作者:美站资讯,如若转载,请注明出处:https://www.meizw.com/n/360896.html

发表回复

登录后才能评论