汇编

概念

ARM汇编指令格式

不同系统种汇编指令有差异

向寄存器种一个值添加100,68K是摩托罗拉的

从一个寄存器指针加载到寄存器

指令条件Cond

状态Status码
如何判断一个立即数是否合规:此数除以4,如果在0-255之间则合规。
0x102:是立即数
0x104:不是立即数

寻址模式

寻址模式

ARM堆栈

  • 满堆栈:堆栈指针指向栈顶
  • 空堆栈:堆栈指针指向栈底
  • 递增堆栈:从低地址向高地址压栈
  • 递减堆栈:从高地址向低地址压栈

汇编算数操作

算术操作

逻辑操作

比较操作

内存操作

单寄存器读取指令

多寄存器操作指令

数据交换指令

跳转与状态操作

跳转实质:给PC传程序地址,告诉CPU下一个执行的程序。
BL:mov LR,PC 这样执行完可以在LR中找到执行记录返回

跳转指令

状态操作

异常产生指令

常用伪指令

汇编常用伪指令

ARM(Thumb)汇编程序所支持的变里有数字变量、逻辑变量和字符串变量

表达式与运算符

寄存器操作

数据定义伪汇编

控制伪指令

混合编程

  • 在C/C++代码中嵌入汇编指令。
  • 汇编调用C/C+
  • C/C++调用汇编

C语言嵌入汇编

格式
限制条件:

  • 不能直接向PC寄存器赋值,程序跳转要使用B或者BL指令;
  • 在使用物理寄存器时,不要使用过于复杂的C表达式,避免物理寄存器冲突;
  • R12和R13可能被编译器用来存放中间编译结果,计算表达式值时可能把R0-R3、R12及R14用于子程序调用,因此避免直接使用这些物理寄存器;

在C中嵌入汇编指令

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
void my_str_cpy(char *src,char *dest)
{
char ch;
__asm{
loop:
LDRB ch,[src],#1 ;每次读取一个字节,指向src的指针加一,然后赋值给ch
STRB ch,[dest],#1 ;将ch赋值给dest,指向src的指针加一
CMP ch,#0 ;比较,字符串最后一位为\0,所以通过比较判断是否读完
BNE loop ;如果ch不等于0,则跳转
}
}

int main()
{
char *a = "hello sunday";
char b[64];
my_str_cpy(a,b);
}

C语言调用汇编

步骤:

  1. 汇编export
  2. c语言定义extern function
  3. c语言使用

C语言和汇编语言之间的参数传递是通过对应的用R0-R3来进行传递,即R0传递第一个参数,R1传递第二个参数,多于4个时借助栈完成,函数的返回值通过Ro来传递。这个规定叫作ATPCS(ARM Thumb Procedure Call Standard),具体见ATPCS规范

1
2
3
4
5
6
7
8
9
10
11
12
13
	AREA myARM,CODE,READONLY
EXPORT my_strcpy

my_strcpy
loop
LDRB R4,[R0],#1
CMP R4,#0
BEQ over
STRB R4,[R1],#1
B loop
over
END

1
2
3
4
5
6
7
extern void my_strcpy(char *src,char *dest);
int main()
{
char *a = "hello sunday";
char b[64];
my_str_cpy(a,b);
}

汇编调用C语言

步骤:

  1. c语言实现函数
  2. 汇编import函数名
  3. BL函数名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
	AREA myARM,CODE,READONLY
EXPORT my_strcpy
IMPORT cFUN
ENTRY

start
MOV R0,#1
MOV R1,#2
MOV R2,#3
BL,cFUN
my_strcpy
loop
LDRB R4,[R0],#1
CMP R4,#0
BEQ over
STRB R4,[R1],#1
B loop
over
END
1
2
3
4
int cFun(int a,int b,int c)
{
return a+b+c;
}