伪操作:不会生成代码,只是在编译之前告诉编译器怎么编译 不同的编译器伪操作也不同
GNU(gcc)的伪操作一般都以 ‘.’ 开头
.global symbol
@ 将symbol声明成全局符号
.local symbol
@ 将symbol声明成局部符号
.equ DATA, 0xFF
@ 似于#define DATA 0xFF
MOV R1, #DATA
.macro FUNC
MOV R1, #1
MOV R2, #2
.endm
FUNC
@ 调用FUNC函数
.if 0
@ 如果条件 0-假, 1-真
MOV R1, #1
MOV R2, #2
.endif
.rept 3
@ 将下面这两行代码重复执行三次
MOV R1, #1
MOV R2, #2
.endr
@.weak symbol
@ 弱化一个符号,即告诉编译器即便没有这个符号也不要报错
.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
@ 下面这条指令将会从2^4 = 16,0x16地址空间开始存储
MOV R2, #2
.arm
@ 告诉编译器后续的代码是ARM指令
.thumb
@ 告诉编译器后续的代码是Thumb指令
.text
@ 定义一个代码段
.data
@ 定义一个数据段
@ .space N, VALUE
@ 在当前地址申请N个字节的空间并将其初始化为VALUE
MOV R1, #1
.space 12, 0x12
@ 32位的处理器,0x4 — 0x16 地址空间将会全部存储12
MOV R2, #2
C和汇编的混合编程原则:在哪种语言环境下符合哪种语言的语法规则
方式一:汇编语言调用(跳转)C语言
汇编中:
MOV R1, #1
MOV R2, #2
BL func_c @ 将会跳到C语言代码中
MOV R3, #3
C语言中:
void func_c() {
int a;
}
方式二:C语言调用(跳转)汇编语言
C语言中:
void func_c() {
int a;
FUNC_ARM(); //将会跳转到汇编指令中
}
汇编中:
MOV R1, #1
MOV R2, #2
.global FUNC_ARM @ 全局变量
FUNC_ARM:
MOV R3, #3
方式三:C内联(内嵌)汇编
asm( “汇编指令\n” );
C语言中:
void func_c(void)
{
int a;
// C内联(内嵌)汇编
asm
(
"MOV R6, #6\n"
"MOV R7, #7\n"
);
}
ATPCS协议(ARM-THUMB Procedure Call Standard)
ATPCS协议主要内容
栈的种类
1.1使用满减栈
寄存器的使用
2.1 R15用作程序计数器,不能作其他用途
2.2 R14用作链接寄存器,不能作其他用途
2.3 R13用作栈指针,不能作其他用途
2.4 当函数的参数不多于4个时使用R0-R3传递,当函数的参数多于4个时,多出的部分用栈传递
2.5 函数的返回值使用R0传递
2.6 其它寄存器主要用于存储局部变量