当前位置: 首页 > biancheng >正文

ARM(GNU)指令集

一、ARM汇编介绍

1、框架

Start.S

.section .data    @数据段(可省略),.section可省略
    <初始化的数据>
.section .bss     @bss段(可省略),.section可省略
    <未初始化的数据>
.section .text    @代码段,.section可省略
.golbal _start
_start:           @程序入口
    <汇编代码>

2、链接器(ld/arm-linux-ld)

-T 指定链接脚本
-o 输出最终可执行二进制文件
-Ttext 指定代码段的起始地址
-Tdata 指定数据段的起始地址
-Tbss 指定未初始化数据段的起始地址

Makefile:
all:start.o
    arm-linux-ld -Text 0x30000000 -o start.elf $^
%.0:%.S
    arm-linux-gcc -g -o $@ $^ -c
clean:
    rm *.o *.elf

3、链接器脚本

SECTIONS{
    . = 0x30000000;    #指出起始地址

    . = ALIGN(4);    #指出该地址四字节对其
    .text :
    {
    main.o (.text)
    *(.text)
    }
    
    . = ALIGN(4);
    .data :
    {
    *(.data)
    }

    . = ALIGN(4);
    bss_start = .;
    .bss :
    {
    *(.bss)
    }
    bss_end = .;
}

二、ARM指令集

1、算数和逻辑指令

(1)mov:赋值

mov R0, R1    @R0=R1

(2)mvn:赋取反值

mvn R0, #4    @R0=~4 -> R0=-5

(3)sub:减法

sub R0, R1, R2    @R0=R1-R2

 (4)add:加法

add R0, R1, R2    @R0=R1+R2

(5)and:逻辑与

and R0, R0, #3    @R0=R0&&3

(6)orr:逻辑或

orr R0, R0, #3    @R0=R0||3

(7)bic:位清除

bic R0, R0, #%1011    @1111 -> 0100

2、比较指令

(1)cmp:比较

cmp R0, R1
    @  R0>R1    CPSR B=0 Z=0
    @  R0=R1    CPSR B=1 Z=0
    @  R0<R1    CPSR B=0 Z=1

(2)tst:按位与 

tst R0, #%1001
    @  (R0 & %1001)=0  -> CPSR Z=1
    @  (R0 & %1001)!=0 -> CPSR Z=0

 3、跳转指令

(1)b:跳转

b [条件] addr

(2)bl:跳转,带返回地址

bl fun    @将返回地址存于lr

使用场景:
fun:
...
mov pc, lr    @lr赋值给pc,实现函数返回

4、移位指令 

(1)lsl:逻辑左移

mov R0, R1, ror#2    @R0=R1<<3

(2)ror:循环右移

mov R0, R1, ror#2    @R0=R1循环右移2位

5、程序状态字访问指令

(1)msr:通过寄存器赋值给程序状态寄存器

msr cpsr, r0    @cpsr=r0

(2)mrs:程序状态寄存器拷贝至通用寄存器

mrs r0, cpsr    @r0=cpsr

6、 存储器访问指令

(1)ldr:将内存拷贝至寄存器

ldr r2, [r1]    @r2=[r1] -> r2=*r1

(2)str:将寄存器拷贝至内存

str r0, [r1]    @[r1]=r2 -> *r1=r2

三、伪指令

1、(32位)机器码组成,一条arm汇编指令的机器码

(1)数据处理机器码(以mov为例)

28-31 (cond)条件
26-27 保留
25    (I)源操作数(0-11位)保存为立即数,则该位为1
31-24 (opcond)指令编码
20    (S)是否影响标志位(CPSR)
16-19 (Rn)第一个源操作数,如果有多个源操作数
12-15 (Rd)目的寄存器
0-11  (shifter_operand)源操作数,mov等指令仅可以赋值8位数据

2、定义类伪指令

(1)global:全局标号
(2)ascii:字符串数据

.data
hello:
.ascii "hello world"
.align 4    @保证bdata地址为4字节对齐
bdata:
.byte 0x1
wdata:
.word 0xff
.golbal _start
_start:

(3)byte:字节数据
(4)word:双字节数据
(5)data:定义数据段
(6)equ:宏定义

3、操作类伪指令

(1)ldr:给寄存器赋值,可以赋值大于8位的数(mov只可以赋值8位以内的数值)

mov r0, #0xff
ldr r0, =x1ff    @可以赋值8位以上的数据,立即数格式不同

(2)nop:空操作,可以用来延时

相关文章:

  • Linux云服务器安全性:如何防范DDoS攻击
  • Allegro_PCB封装创建
  • oracle学习之路(5)Navicat连接Oracle数据库:Oracle library is not loaded 解决方案
  • Wireshark使用教程
  • php彻底解决前端post传递过来的数组decode为null的问题
  • Java中类的加载过程(类的生命周期)详解
  • Mybatis(三):特殊SQL的执行
  • 一篇搞定神经网络(基础篇)
  • Framework事件机制—Event Hub原理及事件解析
  • 求最大公约数和最小公倍数,附python实现