目录
一、伪操作:
二、C和汇编的混合编程
三、ATPCS协议(ARM-THUMB Procedure Call Standard)
一、伪操作:
不会生成代码,只是在编译之前告诉编译器怎么编译
@ GNU的伪操作一般都以‘.’开头
@ .global symbol
@ 将symbol声明成全局符号
@ .local symbol
@ 将symbol声明成局部符号
@ .equ DATA, 0xFF
@ MOV R1, #DATA
@ .macro FUNC
@ MOV R1, #1
@ MOV R2, #2
@ .endm
@ FUNC
@ .if 0
@ MOV R1, #1
@ MOV R2, #2
@ .endif
@.rept 3
@ MOV R1, #1
@ MOV R2, #2
@.endr
@ .weak symbol
@ 弱化一个符号,即告诉编译器即便没有这个符号也不要报错,变成NOP
@ .weak func
@ B func
@ .word VALUE
@ 在当前地址申请一个字的空间并将其初始化为VALUE
@ MOV R1, #1
@ .word 0xFFFFFFFF
@ MOV R2, #2
@ .byte VALUE
@ 在当前地址申请一个字节的空间并将其初始化为VALUE
@ MOV R1, #1
@ .byte 0xFF
@ .align N
@ 告诉编译器后续的代码2的N次方对其
@ .align 4
@ MOV R2, #2
@ .arm
@ 告诉编译器后续的代码是ARM指令
@ .thumb
@ 告诉编译器后续的代码是Thumb指令
@ .text
@ 定义一个代码段
@ .data
@ 定义一个数据段
@ .space N, VALUE
@ 在当前地址申请N个字节的空间并将其初始化为VALUE
@ MOV R1, #1
@ .space 12, 0x12
@ MOV R2, #2
@ 不同的编译器伪操作的语法不同
指令还是伪指令都是由ARM公司来规定的,位操作是根据编译器来的,上述的伪操作都是GNU伪操作,根据Gcc编译器来的,我用的虽然是mdk4但是并没有使用它自带的编译器,使用的是Gcc。
二、C和汇编的混合编程
前三种指令和C语言语句是对应的 而4-6是ARM专有的,别的处理器不一定有这些,所以没有与之对应的C语句。
@ C和汇编的混合编程原则:在哪种语言环境下符合哪种语言的语法规则
@ 1. 在汇编中将C中的函数当做标号处理
@ 2. 在C中将汇编中的标号当做函数处理
@ 3. 在C中内联的汇编当做C的语句来处理
@ 1. 方式一:汇编语言调用(跳转)C语言
@ MOV R1, #1
@ MOV R2, #2
@ BL func_c
@ MOV R3, #3
@ 2. 方式二:C语言调用(跳转)汇编语言
@ .global FUNC_ASM
@ FUNC_ASM:
@ MOV R4, #4
@ MOV R5, #5
@ 3. C内联(内嵌)汇编
void func_c()
{
int a;
a++;
FUNC_ASM();
a--;
}
.text
.global _start
_start:MOV R1, #1
MOV R2, #2
BL func_c
MOV R3, #3
.global FUNC_ASM
FUNC_ASM:
MOV R4, #4
MOV R5, #5STOP:
B STOP
.end
void func_c()
{
int a;
a++;
asm
(
"MOV R6, #6\n"
"MOV R7, #7\n"
);
FUNC_ASM();
a--;
}
三、ATPCS协议(ARM-THUMB Procedure Call Standard)
ATPCS协议主要内容
1.栈的种类
1.1 使用满减栈
2.寄存器的使用
2.1 R15用作程序计数器,不能作其他用途
2.2 R14用作链接寄存器,不能作其他用途
2.3 R13用作栈指针,不能作其他用途
2.4 当函数的参数不多于4个时使用R0-R3传递,当函数的参数多于4个时,多出的部分用栈传递
2.5 函数的返回值使用R0传递
2.6 其它寄存器主要用于存储局部变量
栈比堆效率高,堆需要算法计算空间。