奔跑吧linux-第三章实验
基于树莓派+openeuler平台
实验 3-2:汇编语言练习——查找最大数
1.实验目的
通过本实验了解和熟悉 ARM64 汇编语言。
2.实验要求
使用 ARM64 汇编语言来实现如下功能:在给定的一组数中查找最大数。程序可使用GCC(Aarch64 版本)工具来编译,并且可在树莓派 Linux 系统或者 QEMU + ARM64 实验平台上运行。
实验代码:
.section .data //定义数据段段
.align 3 //以2^3对齐
my_data: //定义一个数据
.quad 1
.quad 2
.quad 5
.quad 8
.quad 10
.quad 12
my_data_count: //数组的个数
.quad 6
.align 3
print_data: //定义一个字符串
.string "big data: %d\n"
.section .text //定义代码段
.globl main //定义入口函数main
main:
stp x29, x30, [sp, -16]! //x29是FP栈帧寄存器,x30是连接寄存器,入栈
ldr x0, =my_data //读取my_data标签的地址
ldr x1, my_data_count //读取my_data_count标签内容(6)
add x4, x0, #40 //数组最后一个数地址,存入x4
mov x3, xzr //x3临时寄存器,初始值0
1:
ldr x2, [x0], #8 //x0地址处的值(数组my_data[0]),加载到x2寄存器,然后更新x0=x0+8
cmp x2, x3
csel x3, x2, x3, hi //csel 条件选择,当条件满足(hi,x2>x3),返回x2,存入x3中,否则返回x3; x3保存最大值
cmp x0, x4 //判断x0是否为my_data最后一个数
b.ls 1b //有条件(无符号小于或等于)跳转1b,
ldr x0, =print_data //加载print_data标签地址
//adrp x0, print_data
//add x0, x0, :lo12:print_data
mov x1, x3 //通过x0,x1传递参数给printf函数
bl printf
ldp x29, x30, [sp], 16 //从start函数栈恢复x29,x30寄存器
ret //函数返回退出
使用指令 gcc 3-2.s -o 3-2 -g
进入gdb调试
main函数设置断点:(gdb) b main
运行test程序:(gdb) r
单步运行:(gdb) s
查看寄存器值:(gdb) info reg x3
查看运行结果:
实验 3-3:汇编语言练习——通过 C 语言调用汇编函数
1.实验目的
通过本实验了解和熟悉 C 语言中如何调用汇编函数。
2. 实验要求
使用汇编语言实现一个汇编函数,用于比较两个数的大小并返回最大值,然后用C 语言代码调用这个汇编函数。程序可使用 GCC(Aarch64 版本)工具来编译,并且可在树莓派 Linux 系统或者 QEMU + ARM64 实验平台上运行。
3、代码
.section .text
.globl compare_data
compare_data:
cmp x0, x1
csel x0, x0, x1, hi # 条件选择指令
ret
#include <stdio.h>
extern int compare_data(int a, int b);
int main()
{
int val;
val = compare_data(5, 6);
printf("big data: %d\n", val);
}
编译指令gcc -o main main.c compare.S --static -g # -g 包含调试信息
运行结果如图:
实验 3-4:汇编语言练习——通过汇编语言调用 C 函数
1.实验目的
通过本实验了解和熟悉汇编语言中如何调用 C 函数。
2.实验要求
使用 C 语言实现一个函数,用于比较两个数的大小并返回最大值,然后用汇编代码调用这个 C 函数。程序可使用 GCC(Aarch64 版本)来编译,并且可在树莓派 Linux系统或者 QEMU + ARM64 实验平台上运行。
代码:
3-4compare.c
int compare_data(int a, int b)
{
return (a >= b) ? a : b;
}
3-4main.s
.section .data
.align 3
print_data:
.string "big data: %d\n"
.section .text
.globl main
main:
stp x29, x30, [sp, -16]!
mov x0, #6
mov x1, #5
bl compare_data
mov x1, x0
ldr x0, =print_data
bl printf
ldp x29, x30, [sp], 16
ret
编译指令gcc -o 3-4main 3-4compare.c 3-4main.s --static -g
运行结果:
实验 3-5:汇编语言练习——GCC 内联汇编
1.实验目的
通过本实验了解和熟悉 GCC 内联汇编的使用。
2.实验要求
使用 GCC 内联汇编实现一个函数,用于比较两个数的大小并返回最大值,然后用 C 语言代码调用这个函数。程序可使用 GCC(Aarch64 版本)工具来编译,并且可在树莓派 Linux 系统或者 QEMU + ARM64 实验平台上运行。
代码:
#include <stdio.h>
static int compare_data(int a,int b)
{
int val;
asm volatile(
"cmp %1, %2\n"
"csel %0, %1, %2, hi\n"
:"+r" (val)
:"r"(a) , "r" (b)
: "memory");
return val;
}
int main()
{
int val;
val = compare_data(5, 6);
printf("big data: %d\n", val);
val = compare_data(6, 4);
printf("big data: %d\n", val);
}
编译指令gcc -o 3-5main 3-5main.c -g
运行结果:
实验 3-6:在树莓派上编写一个裸机程序
环境准备
在不同的平台上进行工程构建的时候,首先需要准备下面的环境:
1.arm交叉编译工具链
2.可用执行makefile的工具
交叉编译工具链arm-none-eabi-gcc-5.4.1可以在官网上进行下载,也可以到网盘中下载:
链接:https://pan.baidu.com/s/1ad3d-pl4YbpgYrxKg6mX9g
提取码:f3cm
树莓派一个
2.树莓派4B的硬件配置
树莓派4b的性能非常强,运行Android和win10也毫无压力。
1.5GHz 4核心64位 ARM Cortex-A72 CPU (~3×倍性能)
1GB/2GB/4GB LPDDR4 SDRAM 内存
全吞吐量千兆以太网
双频 802.11ac 无线网络
蓝牙 5.0
两个 USB 3.0 和两个 USB 2.0 接口
双显示器支持,分辨率高达 4K
VideoCore VI 显卡,支持 OpenGL ES 3.x
HEVC 视频 4Kp60 硬解码
源代码下载
源代码工程已经在GitHub存在了,相关源码可以在如下地址中找到:
https://github.com/bigmagic123/raspi4-bare-metal.git
在arm/1.compilation_environment中可以看到相关的文件列表。
该代码的功能是启动跳转到c代码去执行,然后串口输出hello world程序。
树莓派硬件链接
树莓派4需要准备一张空的SD卡、一个串口线输出信息、一条TYPEC线供电。
首先需要将工程目录的sd_boot下面的文件放到空的SD卡目录中。然后将编译好的kernel7.img放到SD卡中即可。
接着连接串口,给开发板上电,可以在putty等软件看见串口输出信息。
由于目前没有空闲的sd卡,所以最后一步操作将日后完成。