LINUXP

GitHub ARM Assembly Set

Email: BuddyZhang1 buddy.zhang@aliyun.com

目录


MMU

ARM 汇编

ARM汇编指令集

指令:是机器码的助记符,经过汇编器编译后,由CPU执行。

伪指令:用来指导指令执行,是汇编器的产物,最终不会生成机器码。

有两种不同风格的ARM指令

ARM 官方的 ARM 汇编风格:指令一般用大写。

GNU 风格的 ARM 汇编:指令一般用小写。

ARM 汇编的特点

所有运算处理都是发生通用寄存器(一般是 R0~R14 )的之中.所有存储器空间(如C语言变量 的本质就是一个存储器空间上的几个 BYTE).的值的处理,都是要传送到通用寄存器来完成. 因此代码中大量看到 LDR,STR 指令来传送值.

ARM 汇编语句中. 当前语句很多时候要隐含的使用上一句的执行结果.而且上一句的执行结 果,是放在CPSR寄存器里,(比如说进位,为 0,为负…)


MMU

ARM 汇编实践

ARM 汇编实践方法很多,这里提供在 Linux arm32 系统里进行实践。由于本文所介绍的 实践都基于 Linux 5.0 arm32,读者可以根据下文构建 Linux 5.0 arm32 的开发环境:

Linux Arm32 5.0 开发环境搭建教程

在进行实践之前,将所用到的资源如下:

Arm 汇编命令实践代码 Github

ARM 开发手册以及 ARMv7 架构手册

获得实践源码

ARM 汇编提供了很多指令,本文以 MOV 指令为例进行讲解,其他指令实践采用同样的 办法。首先从 Github 上获得 STMEA 指令的实践代码,如下:

/*
 * Arm inline-assembly
 *
 * (C) 2019.03.15 BuddyZhang1 <buddy.zhang@aliyun.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */
#include <linux/init.h>
#include <linux/kernel.h>

#include <linux/mm.h>

/*
 * STMEA (Store Multiple) stores a non-empty subset (or possibly all)
 * of the general-purpose registers to sequential memory locations.
 *
 * Syntax
 *   STM{<cond>}<addressing_mode> <Rn>{!}, <registers>
 */

static unsigned long R0[10];

static int debug_stmea(void)
{
	unsigned long R1 = 0x11;
	unsigned long R2 = 0x22;
	unsigned long R3 = 0x33;
	int i;

	/*
	 * STMIA: Store Register into memory, and empty ascending stack
	 *
	 *
	 *             +-------------+
	 *             |             |
	 *             +-------------+
	 *             |             |
	 *             +-------------+
	 *             |             |
	 *             +-------------+
	 *             |             |
	 *    R0[5]--> +-------------+
	 *             |             |<----------- R1
	 *             +-------------+
	 *             |             |<----------- R2
	 *             +-------------+
	 *             |             |<----------- R3
	 *             +-------------+
	 *             |             |
	 *             +-------------+
	 *             |             |
	 *    R0[0]--> +-------------+
	 *
	 * Push register into empty ascending stack.
	 */

	/* Emulate Stack */
	for (i = 0; i < 10; i++)
		printk("R0[%d] %#lx\n", i, R0[i]);

	return 0;
}
device_initcall(debug_stmea);
添加源码到内核

根据教程搭建好 Linux 5.0 arm32 开发环境之后,将获得的源码驱动加入到 BiscuitOS/output/linux-5.0-arm32/linux/linux/dirvers/BiscuitOS/ 目录下, 修改 Kconfig 文件,如下:

diff --git a/drivers/BiscuitOS/Kconfig b/drivers/BiscuitOS/Kconfig
index 4edc5a5..1a9abee 100644
--- a/drivers/BiscuitOS/Kconfig
+++ b/drivers/BiscuitOS/Kconfig
@@ -6,4 +6,14 @@ if BISCUITOS_DRV
config BISCUITOS_MISC
        bool "BiscuitOS misc driver"
+config BISCUITOS_ASM
+       bool "ARM assembly"

endif # BISCUITOS_DRV

接着修改 Makefile,请参考如下修改:

diff --git a/drivers/BiscuitOS/Makefile b/drivers/BiscuitOS/Makefile
index 82004c9..9909149 100644
--- a/drivers/BiscuitOS/Makefile
+++ b/drivers/BiscuitOS/Makefile
@@ -1 +1,2 @@
obj-$(CONFIG_BISCUITOS_MISC)     += BiscuitOS_drv.o
+obj-$(CONFIG_BISCUITOS_ASM)     += asm.o
--
配置驱动

驱动配置请参考下面文章中关于驱动配置一节。在配置中,勾选如下选项,如下:

Device Driver--->
    [*]BiscuitOS Driver--->
        [*]ARM assembly

基于 Linux 5.x 的 arm32 开发环境搭建教程

驱动编译

驱动编译也请参考下面文章关于驱动编译一节:

基于 Linux 5.x 的 arm32 开发环境搭建教程

驱动运行

驱动的运行,请参考下面文章中关于驱动运行一节:

基于 Linux 5.x 的 arm32 开发环境搭建教程


MMU

ARM 汇编 List

adc

add

and

asl

asr

b

bcc

bcs

beq

bgt

bhi

bhs

bic

bl

ble

blo

bls

blt

bmi

bne

bpl

bvc

bvs

cmn

cmp

eor

ldmda

ldmdb

ldmea

ldmed

ldmfa

ldmfd

ldmia

ldmib

ldr

lsl

lsr

mcr

mla

mov

mrc

mul

mvn

orr

ror

rsb

rsc

sbc

stmda

stmdb

stmea

stmed

stmfa

stmfd

stmia

stmib

str

sub

swp

teq

tst


附录

ARM inline-assembly usermanual

BiscuitOS Home

BiscuitOS Driver

BiscuitOS Kernel Build

Linux Kernel

Bootlin: Elixir Cross Referencer

搭建高效的 Linux 开发环境

赞赏一下吧 🙂

MMU