嵌入式lab2——Arm编程

嵌入式系统实验二

日期:2016-3-30

一、实验目的

  1. 深入理解ARM指令和Thumb指令的区别和编译选项;
  2. 深入理解某些特殊的ARM指令,理解如何编写C代码来得到这些指令;
  3. 深入理解ARM的BL指令和C函数的堆栈保护;
  4. 深入理解如何实现C和汇编函数的互相调用。

二、实验器材

硬件

Ÿ   实验主板一块;

Ÿ   5V/1A电源一个;

Ÿ   microUSB线一根;

以下为自备(可选)器材:

Ÿ   PC(Windows/Mac OS/Linux)一台;

Ÿ   USB-TTL串口线一根(FT232RL芯片或PL2303芯片);

Ÿ   以太网线一根(可能还需要路由器等)。

软件

Ÿ   交叉编译软件

三、实验步骤

使用交叉编译工具或本机编译工具,通过 C 代码和反汇编工具研究:

  1. 生成了 Thumb 指令还是 ARM 指令:如何通过编译参数改变,相同的程序,ARM和Thumb编译的结果有何不同, 如指令本身和整体目标代码的大小等;

①如何通过编译参数改变:

-mthumb:使用这个编译选项生成的目标文件是thumb的。

-mthumb-interwork:指定为thumb的指令使用thumb指令集编译,其余的使用arm,使用这个选项生成的目标文件,允许在thumb和arm之间交叉调用。

②同的程序,ARM和Thumb编译的结果有何不同

嵌入式lab2——Arm编程_第1张图片

嵌入式lab2——Arm编程_第2张图片

可见thumb目标文件大小为8349kb,而arm目标文件大小为8346kb,arm的目标文件比thumb的目标文件大。

  1. 对于 ARM 指令,能否产生条件执行的指令;

在第1题中的测试程序有if-else语句,可以用来测试。

嵌入式lab2——Arm编程_第3张图片

可以看到对于arm指令,程序中条件判断if语句,在反汇编之后有bne指令,说明可以产生条件判断的指令

为了加强理解,将thumb编译的程序也反汇编了一次

嵌入式lab2——Arm编程_第4张图片

  1. 设计 C 的代码场景,观察是否产生了寄存器移位寻址;

嵌入式lab2——Arm编程_第5张图片

嵌入式lab2——Arm编程_第6张图片

在反汇编后没有看到寄存器移位寻址。

但在接下来重新编译并在编译是加入-O1进行优化

嵌入式lab2——Arm编程_第7张图片

发现有ldr r0,[r0,r1,lsl #4]指令,所以有寄存器移位寻址指令。

  1. 设计 C 的代码场景,观察一个复杂的 32 位数是如何装载到寄存器的;

嵌入式lab2——Arm编程_第8张图片

嵌入式lab2——Arm编程_第9张图片

可以看到有指令ldr r3,[pc,#20],20/4+2=7条(此处2考虑了流水线),7条之后读到的指令是.word 0x7831193,正好是长整数2016483646的十六进制。

嵌入式lab2——Arm编程_第10张图片

但此处有疑惑当长整数为1073741824即0x40000000的时候,结果如下,还不能理解:

嵌入式lab2——Arm编程_第11张图片

当长整数为2147483647时,也是:

嵌入式lab2——Arm编程_第12张图片

  1. 写一个 C 的多重函数调用的程序,观察和分析: a. 调用时的返回地址在哪里? b. 传入的参数在哪里? c. 本地变量的堆栈分配是如何做的? d. 寄存器是 caller 保存还是 callee 保存?是全体保存还是部分保存?

嵌入式lab2——Arm编程_第13张图片

嵌入式lab2——Arm编程_第14张图片嵌入式lab2——Arm编程_第15张图片

a. 调用时的返回地址在哪里?

答:由函数最后一个汇编指令可看出返回地址在lr寄存器

b. 传入的参数在哪里?

答:这里最多只有两个参数,所以用了r0和r1,实际上r0~r3都可以作为传参寄存器,但当参数大于4个时,需要用压入堆栈的方式来传参。

c. 本地变量的堆栈分配是如何做的?

答: 本地变量首先存在r0、r1和r2中,其他的通过r3压入堆栈中。

d. 寄存器是 caller 保存还是 callee 保存?是全体保存还是部分保存?

答:caller保存参数,callee保存地址;

部分保存,只保存需要保存的。

  1. MLA 是带累加的乘法,尝试要如何写 C 的表达式能编译得到 MLA 指令。

嵌入式lab2——Arm编程_第16张图片

嵌入式lab2——Arm编程_第17张图片

  1. BIC是对某一个比特清零的指令,尝试要如何写 C 的表达式能编译得到 BIC 指令。

嵌入式lab2——Arm编程_第18张图片

嵌入式lab2——Arm编程_第19张图片

  1. 编写一个汇编函数,接受一个整数和一个指针做为输入,指针所指应为一个字符串,该汇编函数调用C语言的 printf()函数输出这个字符串的前n个字符,n即为那个整数。在C语言写的main()函数中调用并传递参数给这个汇编函数 来得到输出。

嵌入式lab2——Arm编程_第20张图片

嵌入式lab2——Arm编程_第21张图片

把二进制文件反汇编:

嵌入式lab2——Arm编程_第22张图片

嵌入式lab2——Arm编程_第23张图片

把可执行文件通过samb共享到acadia板子上并运行:

的确输出了“Hello,welcome to here!”的前十位。

四、实验感想

通过这一次的实验,熟悉了arm的一些基本指令,了解了arm和thumb指令的一些特点。因为是第一次接触,所以这一次的实验过程中还是遇到了很多问题,各种arm指令的含义以及如何产生等。但是最后完成了还是蛮开心的






你可能感兴趣的:(嵌入式lab2——Arm编程)