Makefile编写(6.17)

来源:互联网 发布:我想开淘宝 编辑:程序博客网 时间:2024/04/27 14:46
一  Makefile编写


目标:依赖文件
<tab>命令


工作原理:
make读取Makefile文件,找到指定的目标
[1]依赖文件是否存在
<1>依赖文件存在,则判断依赖文件和目标谁更新,如果此时依赖文件比目标文件新[说明依赖文件发生了修改]则执行底下的命令
<2>依赖文件不存在,则在Makefile寻找生成依赖的文件目标,有执行对应的目标生成依赖文件,然后执行底下的命令,没有则报错
 
--------------------------------------------------------------------------------------------------------------------------


目标:
<tab>命令


此时执行目标的命令




注意:
[1]make       => 当make读取Makefile文件的时候,默认执行的是第一个目标
[2]make 目标  => 寻找指定目标执行




二 ARM的指令集系统


RISC


设计cpu核: ARM7    ARM9    ARM10   ARM11   cortex-A8   cortex-A9
对应指令版本  ARMv4   ARMv4   ARMv5   ARMv6    ARMv7       ARMv7


注意:
<1>高版本的指令兼容低版本
<2>每个新版本发布的时候,都会增加新设计的指令
<3>编译器翻译的指令版本要和ARM核识别的指令版本统一




三  ARM常用的指令


1.指令格式


助记符号{条件}{s}  目标寄存器,第一个操作数,第二个操作数


<1>助记符号就是汇编指令的名称  ADD,SUB,AND...
<2>条件:可选,只有在条件成立的时候,指令才会执行
   eq(相等),ne(不相等),gt(大于),lt(小于),ge(大于等于),le(小于等于)
   
<3>s            :可选,表示指令执行的结果影响CPSR的N,Z,C,V位


<4>目标寄存器  : r0-r15


<5>第一个操作数:必须是寄存器,r0-r15  


<6>第二个操作数:多种形式
[1]立即数:如果一个数字可以由[0-255]中的一个数循环右移偶数位得到,则这个数为合法立即数
   表示形式  #数字
 
[2]寄存器
r0-r15
 
[3]寄存器移位
 逻辑移位 : lsl(左移)  lsr(右移)
 算术移位 : asr(右移:此时左边补的是符号位)
 
 表示形式  r0,lsl #3   => r0 << 3  (将r0读取后左移3位作为第二个操作数)
 
 错误写法  #3,lsl #3 (只能是寄存器移位)
 


2.数据传送指令
  [1]mov  目标寄存器,第二个操作数
     mov r0,#3        -> r0 = 3
     mov r0,r1    -> r0 = r1
     mov r0,r1,lsl #3 -> r0 = r1 << 3
     
[2]mvn   目标寄存器,第二个操作数
  mvn   r0,#0  -> r0 = ~0
  mvn   r0,r1     -> r0 = ~r1
  
[3]ldr    目标寄存器,=任意的数据
  ldr    r0,=0x12345678  -> r0 = 0x12345678
  ldr    r0,=r1(错误)
  ldr    r0,=#0x3(错误)
   
3.数据运算指令
[1]加法指令
  ADD 目标寄存器,第一个操作数,第二个操作数
 
ADD r0,r1,r2        -> r0 = r1 + r2 
add r1,r0,#3        -> r1 = r0 + 3
add r2,r0,r1,lsr r3 -> r2 = r0 + (r1 >> r3)
 
 
[2]减法指令  
 SUB 目标寄存器,第一个操作数,第二个操作数
 
[3]乘法指令
 MUL 目标寄存器,第一个操作数,第二个操作数
 
 注意:
 <1>第一个操作数和第二个操作数必须是寄存器
 <2>目标寄存器编号,不能和第一个操作数寄存器编号相同
 
   练习:1 + 123 * 4 - 5,最终的结果存放在r0中

  [4]按位与
  AND 目标寄存器,第一个操作数,第二个操作数
   
  AND   r0,r1,#3  -> r0 = r1 & 3
 
  [4]按位或
  ORR 目标寄存器,第一个操作数,第二个操作数
   
  ORR  r0,r1,#3  -> r0 = r1 | 3
 
  [5]异或
  EOR 目标寄存器,第一个操作数,第二个操作数 
   
  EOR  r0,r1,#3  -> r0 = r1 ^ 3
   
  练习:0x12345678,将这个数的高16位和低16位相加,最终的结果存放在r0
 
  0x12345678 & 0xffff0000  -> 0x12340000

[6]位清除
BIC  目标寄存器,第一个操作数,第二个操作数 
 
BIC  r0,r1,#3  -> r0 = r1 & ~3

总结:第二个数为1的位清除第一个操作相应的位

练习:0xabcd,将这个数的[5-6]位清0,将这个数的[8-10]位变成101,其他位不变
 
 15 14 13 12 11 10 9  8  7  6  5  4  3  2  1  0
1  0  1  0  1  0  1  1  1  1  0  0  1  1  0  1
 
 int data = 0xabcd;
 
 data = data &  ~(3 << 5) 
 
 mov r1,#3
 BIC r0,r0,r1,lsl #5 => r0 = r0 & ~(r1 << 5) = 0xabcd & ~(3 << 5) 
 
 0000000 1 1 00000 
      
 data = data & ~(7 << 8);
 
 15 14 13 12 11 10 9  8  7  6  5  4  3  2  1  0
1  0  1  0  1  0  0  0  1  1  0  0  1  1  0  1
 
 data = data | (0x5 << 8);    
     


4.比较指令
cmp  第一个操作,第二个操作数

注意:cmp指令运行的结果自动影响cpsr的N,Z,C,V

a = 10;
if(a > 3)
a ++;

mov r0,#10

cmp r0,#3
addgt r0,r0,#1


练习:
a = 10
b = 20
 
if(a > b)
a ++;
else 
 b ++;




5.跳转指令

B/BL   标签名
  功能:跳到指定的标签取指令执行
 
  注意:
  <1>BL跳到指定标签的时候,会将当前pc的值保存到lr
  <2>跳转范围 +/- 32M


 
练习:
 1 + 2 + 3 + ... + 100 ,最终的累加和存放在r0
 
 int i;
 int sum = 0;
 
   for(i = 1;i <= 100;i ++)
   {
    sum = sum + i;
   }
   


6.内存访问指令
  str(store) : 将寄存器的值存储到内存 [写内存]
  ldr(loder) : 将内存的值加载到寄存器 [读内存]
 
  str/ldr  寄存器1,[寄存器2] 
 
  注意:寄存器2的值作为内存的地址
 
  ldr r0,=0x20000
  mov r1,#10
 
  str r1,[r0]  => *r0 = r1  
  ldr r2,[r0]  => r2  = *r0  
 
 
常用表现形式:
[1]前索引
str/ldr r0,[r1,#4]   *(r1 + 4) = r0 /  r0 = *(r1 + 4)

[2]后索引
str/ldr r0,[r1],#4   *r1 = r0, r1 = r1 + 4  / r0 = *r1, r1 = r1 + 4

[3]自动索引
str/ldr r0,[r1,#4]! *(r1 + 4) = r0,r1 = r1 + 4 / r0 = *(r1 + 4),r1 = r1 + 4
 
  思考:向基地址0x24000 写入1,2,3,4,5,6,8,9,10
 
 
  练习:
  1.向基地址0x24000 写入0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,0x88,0x99
  2.将0x24000开始的10个数据,拷贝到0x340000
 
  int i = 0;
  int data = 0;
  int *p = (int *)0x24000;
 
  for(i = 0;i < 10;i ++)
  {
  data = (i << 4) | i;
  *p = data;
  p ++;
  }
 
  10000 | 1 
  10001 =>0x11
 
  10 0000 | 0010
  10 0010 => 0x22 
 
  //内存拷贝
  int i = 0;
  int data;
  int *src = (int *)0x24000
  int *des = (int *)0x34000 
 
  for(i = 0;i < 10;i ++)
  {
  data = *src;
  *des = data;
 
  src ++;
  des ++;
  }
 
7.多寄存器装载指令
LDM{cond}<模式>   Rn{!},{reglist} 
STM{cond}<模式>   Rn{!},{reglist}


<1>cond:指令执行的条件;可选


<2>模式:控制地址的增长方式
IA(increase after)  : 先操作寄存器,后增加地址
IB(increase before) : 先增加地址,后操作寄存器
 
DA(decrement after) : 先操作寄存器,后减少地址
DB(decrement before):先减少地址,后操作寄存器


<3>Rn  : 基地址寄存器(保存了内存的首地址)


<4>!   :表示在操作结束后,将最后的地址写回Rn中;可选,通常我们都使用它


<5>reglist :表示寄存器列表,可以包含多个寄存器,它们使用“,”隔开,如{R1,R2,R6-R9}

注意:
  [1]寄存器由小到大排列
[2]大地址对应大寄存器编号,小地址对应小寄存器编号


8.栈操作指令
ldmfd sp!,{寄存器列表}  [出栈]
stmfd sp!,{寄存器列表}  [进栈]

注意:
[1]在对栈操作之前,必须先设置sp的值
[2]进栈和出栈的方式一样,ATPCS标准规定满减栈
0 0
原创粉丝点击