1. 程式人生 > 其它 >奔跑吧linux-第三章實驗

奔跑吧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、程式碼

//compare.s:

.section .text
.globl compare_data
compare_data:
	cmp x0, x1
	csel x0, x0, x1, hi # 條件選擇指令
	ret

//main.c

#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卡,所以最後一步操作將日後完成。