ARMday2

目录

一、示例汇编代码示例

二、.程序的调试

​编辑三、map.lds分析

四、【汇编语言的相关语法】

1、汇编文件中的内容

2.汇编指令的基本语法格式

五、【汇编的指令】

1.数据搬移指令

1.1 基本格式

1.2 示例

​编辑2. 立即数的概念

2.1 概念

2.2 立即数的判断

​编辑2.3 如何将一个非立即数保存在寄存器中

​编辑3.移位操作指令

3.1 指令格式以及指令码

3.2 示例

​编辑4.位运算指令

4.1 相关指令功能以及规则

 4.2 位运算指令码以及格式

 4.3 示例

5.算数运算指令

5.1 指令码以及格式

5.2 示例代码

​编辑5.3 进行64位算数运算

6.数据比较指令

6.1 语法

​编辑6.2 示例

7.跳转指令

任务

1.复习今日内容

2.实现1-100,累加


 

一、示例汇编代码示例

.text   @声明当前内容为文本段内容

.global _start  @声明_start的内容为全局内容

_start:
       mov r1,#1   @将1保存在r1寄存器

loop:  
     b loop  @程序跳转到loop标签
    
.end  @程序结束

二、.程序的调试

三、map.lds分析

map.lds文件是一个链接脚本文件 链接脚本的作用:当程序在编译的最后一个阶段-链接阶段中按照链接脚本的规定,链接不同的文件生成可执行文件

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*指定输出elf格式的适用于32位机器的镜像,镜像内部的数据按照小端存储方式 */
OUTPUT_ARCH(arm)/*生成的镜像架构是ARM架构的 */
ENTRY(_start)/*  程序执行的入口是_start*/
SECTIONS  /* 内部指定了不同内容在内存中的存储位置*/
{
    . = 0x00000000;  /*当前程序起始地址为0X0*/
    . = ALIGN(4);/*程序中的指令遵循4字节对齐*/
    .text      :   /*指定文本段的存储地址*/
    {
        ./Objects/start.o(.text)  /*将start.o的内容放在文本段最开始*/
        *(.text)/*其他的文件保存位置由链接器自己决定*/
    }
    . = ALIGN(4);
    .rodata : /*规定只读代码段的存储规则*/
    { *(.rodata) }
    . = ALIGN(4);
    .data : 
    { *(.data) }
    . = ALIGN(4);
    __bss_start = .; /*指定.bss段的起始位置*/
    .bss :
     { *(.bss) }
    __bss_end__ = .;/* 指定.data段的起始位置*/
}

四、【汇编语言的相关语法】

1、汇编文件中的内容

1.伪操作:在汇编程序中不占用存储空间,但是可以在程序编译时起到引导和标识作用
.text .global .glbal .if .else .endif .data  .word....
2.汇编指令:每一条汇编指令都用来标识一个机器码,让计算机做一个指令运算
    数据处理指令
        数据搬移指令
        算数运算指令
        数据移位指令
        位运算指令
        数据比较指令        
    跳转指令    
    内存读写指令
    状态寄存器传送指令   CPSR 
    软中断指令   
3.伪指令:不是汇编指令,但是也可以让处理器做一些数据处理,通常一条伪指令会由多条汇编指令联合实现  

4.注释
单行注释:  @   ;
多行注释:  /*  */
条件注释
.if 1/0
    指令段1
.else
    指令段2
.endif

2.汇编指令的基本语法格式

指令的基本格式:
<opcode>  {<cond>}  {s}  <Rd>,  <Rn>,  <shifter_operand>

<opcode>:指令的操作码
 cond:条件码后缀
 s:指令的执行结果将会影响CPSR中的条件标志位。
 <Rd>:目标寄存器,指令的运算结果保存在目标寄存器中
 <Rn>:第一操作寄存器,只能是寄存器
<shifter_operand> :第二操作数,既可以是寄存器编号,又可以是立即数
意义:让第一操作寄存器中的值和第二操作数按照指令操作码进行运算,并且将运算的结果保存在目标寄存器中 

  注意:
  1.一般一条汇编指令就占据一行代码
  2.汇编不区分大小写
  3.操作数前面要跟一个#

五、【汇编的指令】

1.数据搬移指令

1.1 基本格式

<opcode>  {<cond>}  {s}  <Rd>,  <shifter_operand>
 解释:
 
<opcode>:指令的操作码
 cond:条件码后缀
 s:指令的执行结果将会影响CPSR中的条件标志位。
 <Rd>:目标寄存器,指令的运算结果保存在目标寄存器中
<shifter_operand> :第一操作数,既可以是寄存器编号,又可以是立即数

指令码:
mov:将操作数直接搬移到目标寄存器中
mvn:将操作数按位取反之后搬移到目标寄存器中

1.2 示例

2. 立即数的概念

2.1 概念

定义:可以直接当作指令的一部分去执行的数据叫做立即数。立即数是通过一个0-255之间的数字循环右移偶数位获取

循环右移:低位移除,补到高位

2.2 立即数的判断

如何判断一个数据是不是立即数:
    只要让这个数据或者这个数据按位取反的值循环右移偶数位,能够得到一个0-255范围内的数字就说明这个数是立即数

ex:
   1. 0X104->  0000 0000 0000 0000 0000 0001 0000 0100
    0X104循环右移两位-》00 0000 0000 0000 0000 0000 0001 0000 01->0x41
    0X41是一个0-255范围内的数据    
0x104是0X41循环右移30位得到的数据,所以,0X104是立即数

2.0x101-> 0000 0000 0000 0000 0000 0001 0000 0001
0X101找不到一个0-255范围内的数字寻魂右移偶数位得到它,所以它不是立即数

3.0XFFFFFFFE ->1111 1111 1111 1111 1111 1111 1111 1110
0XFFFFFFFE也找不到0-255范围内的数字循环右移偶数位得到它,但是它的取反值0X1是一个立即数,所以0XFFFFFFFE也是一个立即数

2.3 如何将一个非立即数保存在寄存器中

利用伪指令ldr即可完成非立即数的操作 格式: ldr 目标寄存器名,=数据

3.移位操作指令

3.1 指令格式以及指令码

格式:
<opcode>  {<cond>}  {s}  <Rd>,  <Rn>,  <shifter_operand>
解释:将第一操作寄存器的数值移位第二操作数位,将结果保存在目标寄存器中

指令码:
lsl:左移运算,最高位移出,最低位补0
lsr:右移运算,最低位移出,最高位补0
ror:循环右移:最低位移出,补到最高位

3.2 示例

​
text
.global _start
_start:
    mov r0,#0XFF
    lsl r1,r0,#4 @0XFF左移四位结果保存到r1 0XFF0
    lsr r2,r0,#4 @0XFF右移移四位结果保存到r2 0XF
    ror r3,r0,#4 @0XFF循环右移四位结果保存到r3 0XF000000F
loop:  
    b loop
    
.end

​

4.位运算指令

4.1 相关指令功能以及规则

与、或、异或、按位清0

与:与0清0 与1不变

初值

运算值

结果

1

0

0

1

1

1

0

1

0

0

0

0

或:或1置1 或0不变

初值

运算值

结果

1

0

1

1

1

1

0

1

1

0

0

0

异或:相同为0,不同为1 

初值

运算值

结果

1

0

1

1

1

0

0

1

1

1

1

0

按位清0:想要哪位清0,只需要和1进行运算即可

初值

运算值

结果

1

1

0

0

1

0

1

0

1

0

0

0

 4.2 位运算指令码以及格式

格式:
<opcode>  {<cond>}  {s}  <Rd>,  <Rn>,  <shifter_operand>

指令码:
    and:进行按位与
    orr:进行按位或
    eor:按位异或
    bic:按位清0

 4.3 示例

.text
.global _start
_start:
    mov r0,#0XFF
    and r1,r0,#(~(0X1<<4)) @第四位清0 0xEF
    orr r2,r0,#(0X1<<9) @第9位置1  0X2FF
    eor r3,r0,#0XF  @0xf0
    bic r4,r0,#(0X1<<4)@第四位清0 0xEF
loop:  
    b loop
    
.end
    

5.算数运算指令

5.1 指令码以及格式

格式:
<opcode>{<cond>}{s}  <Rd>,  <Rn>,  <shifter_operand>

指令码:
add:加法运算     Rd=Rn+shifter_operand
adc:进行加法运算时考虑CPSR的C位  Rd=Rn+shifter_operand+CPSR[c] 
sub:减法运算    Rd=Rn-shifter_operand
sbc:进行减法运算时考虑CPSR的c位    Rd=Rn-shifter_operand-!CPSR[c]
RSB
:逆向减法Rd=shifter_operand-Rn
RSC:带借位的逆向减法指令  Rd = shifter_operand – Rn - !CPSR[c]


mul:乘法运算  Rd=Rn*shifter_operand

5.2 示例代码

加法

.text
.global _start
_start:
    mov r0,#0XFFFFFFFE
    mov r1,#3
    adds r2,r0,r1  @0X1,运算的结果影响到条件位
    adc r3,r1,r2  @r3=r1+r2+CPSR[c]
    
loop:  
    b loop
    
.end
    
    

减法:

.text
.global _start
_start:
    mov r0,#0XFFFFFFFE
    mov r1,#3
    subs r2,r1,r0 @减法不借位,c位置1,借位,c位清0
    mov r3,#6
    sbc r4,r3,r1  @r4=r3-r1-!CPSR[c]
    
    
loop:  
    b loop
    
.end
    
    

5.3 进行64位算数运算

MOV R1,#0xfffffffe  @第一个数据的低32位
mov r2,#0x00000004 @第一个数据的高32位

MOV R3,#0x00000005  @第二个数据的低32位
mov r4,#0x00000004 @第二个数据的高32位
加法:
低32位:
    adds r5,r1,r3
高32位:
    adc r6,r2,r4
    
减法:
 低32位:
    subs r5,r3,r1
高32位:
    sbc r6,r4,r2   

6.数据比较指令

6.1 语法

格式:
    cmp  <Rn>,  <shifter_operand>
比较指令的本质:
    拿第一操作寄存器和第二操作数进行减法运算,并且减法运算的结果会影响到CPSR的条件位
    
    
可以根据比较指令之后的条件位的数值进行不同的运算,相当于c里的选择语句
这里需要对CPSR的条件位进行判断,我们依赖条件位的助记词{cond}后缀实现

6.2 示例

.text
.global _start
_start:
  MOV R1,#4
  MOV R2,#4
  CMP R1,R2
  addeq r3,r1,r2  @if(r1==r2)  r3=r1+r2
  subne r4,r1,r2  @if(r1!==r2)  r4=r1-r2
loop:  
    b loop
    
.end
    

7.跳转指令

一般实现程序的跳转有两种方式:
    1.直接修改PC的值
    2.通过跳转指令
跳转指令:

1.b label
    解释:跳转到label标签所在代码,此时跳转,lr寄存器不保存返回地址
    ex:
.text
.global _start
_start:
  MOV R1,#4
  MOV R2,#4
  CMP R1,R2
  beq addfunc
  bne subfunc
 
 addfunc:
    add r3,r1,r2
    b loop
subfunc:
    sub r4,r1,r2  @if(r1!==r2)  r4=r1-r2
    b loop
loop:  
    b loop
    
.end
    
    2. bl label
 解释:跳转到label标签所在代码,此时跳转,lr寄存器保存返回地址
 
ex:
    .text
.global _start
_start:
  MOV R1,#4
  MOV R2,#4
  CMP R1,R2
  bleq addfunc
  blne subfunc
 
 addfunc:
    add r3,r1,r2
    mov pc,lr  @程序返回
subfunc:
    sub r4,r1,r2  @if(r1!==r2)  r4=r1-r2
    mov pc,lr  @程序返回
loop:  
    b loop
    
.end
    
    3. bx 地址
 跳转到地址对应的的指令位置,此时跳转LR不保存返回地址
 .text
.global _start
_start:
  MOV R1,#4
  MOV R2,#4
  MOV R3,#4
  MOV R4,#4
  MOV R5,#4
  MOV R6,#4
  bx r3  @跳转到地址为4的指令位置
  
loop:  
    b loop
    
.end
    
    4.blx 地址
 跳转到地址对应的的指令位置,此时跳转LR保存返回地址
 
 .text
.global _start
_start:
  MOV R1,#4
  MOV R2,#4
  MOV R3,#4
  MOV R4,#4
  MOV R5,#4
  blx r3  @跳转到地址为4的指令位置
  MOV R6,#4
 
  
loop:  
    b loop
    
.end
    
    

任务

1.复习今日内容

2.实现1-100,累加

.text  
.global start 
            

_start:
    mov r0,#0  @存放sum
    mov r1,#1   @存放相加的数值
loop:
    cmp r1,#100
    bhi wh
    add r0,r0,r1
    add r1,r1,#1
    b loop        
wh: 
    b wh  
    
.end 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值