本专栏总结王利涛《C语言嵌入式Linux高级编程》第二期课程
文章目录
一、ARM与GNU编译器
1)常用ARM开发环境
- IAR
- ADS1.2/SDT :ARM software Development kit
- RVDS:Realview Developer Suite
- Keil MDK
- Real View MDK
- GNU ARM交叉编译器
2)ARM编译器
- ARM编译器
- GNU arm-linux-gcc bianyiqi
二、编译器是一套工具
arm编译器是一套工具,包含:
- 编译器有:gcc、g++
- 汇编器、链接器:as、ld
- 二进制转换工具:objdump、objcopy-strip
- 打包工具:ar
- 调试工具:gdb
- 库/头文件
三、ARM编译器与ARM GNU编译器区别(主要是汇编器)
1)编译器设计的参考标准
这两个编译设计都是参考 ARM指令集。
2)编译器设计实现
- 标准指令:将高级程序翻译成ARM指令集规定的汇编指令。
- 伪操作:将汇编指令组装成一个可运行的汇编程序。
- CPU内部的电路,决定了ARM的指令集。ARM编译器 和 ARM GNU编译器的设计参考了ARM指令集,并且各自的编译器都要属于自己的伪操作。编译器的作用是用来做翻译工作,将高级语言,转换成ARM指令集规定的汇编。
3)编译器之间的伪操作差异
ARM编译器 | ARM GNU编译器 |
---|---|
AREA copy, CODE,… | .text |
AREA dat, DATA,… | .data |
使用 ;注释 | 使用/* */或@ 注释 |
DCD | .long / .word |
Entry | Entry: |
END | .end |
CODE32 | .arm/.code32 |
SPACE | .space |
GBLL/GBLA | .global |
EXPORT | .global |
IMPORT | .extern |
EQU/SETL/SETA | /equ/.set |
label | label: |
:OR | 1 |
:SHL: | << |
IF:DEF:ELSE ENDIF | .ifdef .else .endif |
MACRO | .macro |
MEND | .endm |
GET test.h | .include “test.h” |
四、ARM GNU编译常用伪操作
伪操作 | 说明 |
---|---|
ENTRY(_start) | 定义程序入口 |
@ | 注释 |
.section .text/.data | 定义段 |
.align | 地址对齐方式 |
.quand / .long / .word | 整型数据定义 |
.byte/ .short | 整形数据定义 |
.string / .ascii / .asciz | 字符串定义 |
.float | 浮点数定义 |
.space 10 FF | 分配10个字节空间,填充为FF |
.equ / .set | 赋值语句 |
.type func, @ function | 指定符号类型为函数 |
.type num, @boject | 指定符号类型为对象[object->常数、变量] |
.include / .incbin | 展开头文件/二进制文件 |
tmp .reg / .unreg r12 | 给寄存器取别名 |
.arm / .code32 | 指定指令集格式 |
.thumb / .code16 | 指定指令集格式 |
.poll / .ltory | 声明一个文字池 |
.comm buf ,20 | 在BSS段申请一段buf(未初始化) |
OUTPUT_ARCH(arm) | 指定可执行文件运行平台 |
OUT_FOR MAT (“elf32-littlearm”) | 指定输出可执行文件格式 |
; / \n\t | 汇编语句分隔符 |
# / $ | 指定指令集版本 |
.arch | 指定指令集版本 |
.file | 汇编对应的C源文件 |
.fpu | 浮点类型 |
五、GNU汇编中的标号
1)使用规则
- 由字幕、数字、下划线和 . 等字符组成;
- 局部标号由数字 N 组成,引用 :NF或Nb,表示往前或往后搜索;
2)程序气短标号:_start
- ARM GUN汇编默认使用 _start标号作为汇编程序的起点;
- 如果希望该标号被其它文件引用,需要 .global _start 声明一下。
六、section伪操作
1)使用方法
- 用户通过 .section伪操作定义一个段;
- 格式:
.section <section_name> {, "<flags>"}
- .section , mysection(段名) “awx" @定义一个允许可写、可执行段
- 每个段以段名开始,以下一个段名或文件结尾为结束
- 系统预留的段名不可冲突:.text / .data / .bss /…
七、GNU-ARM 汇编中的常数
基本数据格式
- 二进制以 0b/0B 开头,八进制以 0开头,十六进制以0x开头,十进制以非0常数开头;
- 负数前加“-” ,取补用“~”, 不相等用“<>”, 其它符号: + - * % < << > >> | & ^;
- 字符串常量用双引号 " " 括起来;
- 当前地址可以用
.
表示,.
在汇编程序代表当前指令的地址; - 使用
.ascii "hello\0"
定义字符串要自行结尾加‘\0’
,
.string可以定义多个字符串:.string "hello", "world"
ascize 可以定义一个以空字符结尾的字符串:.asciz "hello "
- 使用 .rept 重复定义数据:
.rept 3 .byte 0x10 .endr
连续定义3个.byte 0x10
八、数据定义
1)基本格式
-
标签:命令
f: .float 3.14
-
符号赋值
.eque f, 10
2)定义静态符号
-
.equ除了赋值外,使用.equ 可以把常数定义为可以在代码段中使用的符号,类似于C语言中的#define 宏定义
.section .data .equ DELAY, 100 .section .text mov R0, $DELAY