基本汇编指令

指令格式说明

汇编指令的总体构成如下:
opcode{cond}{s} Rd, Rn, oprand2

每个替代符号的含义:
opcode 指令名称, 必须有, 否则无法构成一条指令

cond 条件码, 可选, 使用时跟指令名称和在一起写, 如指令mov和条件码eq, 应当写成 moveq 只要指令格式中有{cond}就代表这条可以使用条件码

s 状态码, 可选, 跟条件码一样, 要跟指令合并在一起写

Rd destination register, 目标寄存器, 指令的最终运算结果要保存到的寄存器

Rn 第N号寄存器, 第一个操作寄存器, 就是说在这个位置必须是某个寄存器

oprand2 操作数, 第二个操作数, 就是说, 在这个位置, 可以是一个寄存器, 也可以是一个立即数, 也可以是一个表达式

赋值指令
搬移指令mov
语法格式:mov{cond}{s} Rd, oprand2
功能: 将操作数 oprand2 保存到 Rd 寄存器中
例:
    mov R0 #0xFF
    mov R0 R1
取反搬移指令mvn
语法格式:mvn{cond}{s} Rd, oprand2
功能: 将操作数 oprand2 取反后保存到 Rd 寄存器中
例:
    mvn R0 #0xFF
    mvn R0 R1
伪指令 ldr
指令ldr
伪指令有很多, ldr只是其中一例, 这里列出ldr就是为了呈现伪指令的样子。
语法格式: ldr Rd, =num
功能:将操作数保存到Rd中, num可以是任意数, 不用关心是否为立即数
例:
    ldr r0, =0x12345678
算数运算指令
加法指令add(忽略状态位):
语法格式: add{cond}{s} Rd, Rn, oprand2 
功能: 将两个操作数相加, 结果保存到Rd中, 忽略状态位
例:
    add     r0, r1, #18     @ 不影响状态位
    adds    r0, r1, #18     @ 影响状态位
    addlt   r0, r1, #18	    @ 满足条件时才相加
状态加法指令adc(操作状态位):
语法格式: adc{cond}{s} Rd, Rn, oprand2 
功能: 将两个操作数相加, 结果保存到Rd中, 并加上状态C位
例:
    adc     r0, r1, #18     @ 不影响状态位
    adcs    r0, r1, #18     @ 影响状态位
    adclt   r0, r1, #18		@ 满足条件时才相加
减法指令sub(忽略状态位):
语法格式: sub{cond}{s} Rd, Rn, opand2
功能:使用Rn减去opand2, 结果保存到Rd中, 忽略状态位
例:
    sub     r0, r1, #18     @ 不影响状态位
    subs    r0, r1, #18     @ 影响状态位
    sublt   r0, r1, #18
状态减法指令sbc(操作状态位):
语法格式: sbc{cond}{s} Rd, Rn, opand2
功能: 使用Rn减去opand2, 结果保存到Rd中, 并减去!C
例:
    sbc     r0, r1, #18     @ 不影响状态位
    sbcs    r0, r1, #18     @ 影响状态位
    sbclt   r0, r1, #18
乘法指令mul
语法格式: mul{cond}{s} Rd, Rn, oprand2
功能: 两数相乘, 结果保存到Rd中
例:
    mul     r0, r1, #18
    mul     r0, r1, r2
比较运算指令
比较指令cmp
语法格式: cmp Rn, oprand2
功能: 影响NZCV位, 产生比较结果
注意: cmp指令没有目标寄存器, 它只影响状态寄存器
cmp本质上是 Rn - operand2
例:
    cmp r0, #5
    cmp r0, r1
load/store单寄存器内存读写指令
读内存指令ldr ldrh ldrb
助记: ld ===> load 读取
       h ===> half 半字
       b ===> byte 字节
语法格式: 
    普通读写:
        ldr{cond} Rn, [Rm]  从地址Rm对应内存读取1个字的内容
        ldrh{cond} Rn, [Rm] 从地址Rm对应内存读取半字内容
        ldrb{cond} Rn, [Rm] 从地址Rm对应内存读取1个字节的内容
            
    内存地址索引方式读写:
    1. 前置索引
        ldr{cond} Rn, [Rm, #4]  从地址Rm+4对应内存读取1个字的内容
        ldrh{cond} Rn, [Rm, #4] 从地址Rm+4对应内存读取半字内容到
        ldrb{cond} Rn, [Rm, #4] 从地址Rm+4对应内存读取1个字节的内容

    2. 后置索引
        ldr{cond} Rn, [Rm], #4 从地址Rm对应内存读取1个字的内容
                            并将Rm的地址修改为Rm + 4
        ldrh{cond} Rn, [Rm], #4 从地址Rm+4对应内存读取半字内容到
                            并将Rm的地址修改为Rm + 4
        ldrb{cond} Rn, [Rm], #4 从地址Rm+4对应内存读取1个字节的内容                    
                            并将Rm的地址修改为Rm + 4

    3. 自索引
        ldr{cond} Rn, [Rm, #4]! 从地址Rm+4对应内存读取1个字的内容
                                同时将Rm的地址修改为Rm + 4
        ldrh{cond} Rn, [Rm, #4]! 从地址Rm+4对应内存读取半字内容到
                                同时将Rm的地址修改为Rm + 4
        ldrb{cond} Rn, [Rm, #4]! 从地址Rm+4对应内存读取1个字节的内容
                                同时将Rm的地址修改为Rm + 4
    
功能: 将Rm的值读取到Rn寄存器中
注意: Rm 相当于指针, [Rm] 相当于取出指针所指向地址的值
例:
    ldr r0, =0xFFFFFFF5     @将地址保存到r0寄存器中
    ldr r0, [r0]            @取出r0所指向的值, 保存到r0中
    ldr r0, =0x12345678     @读取结果:0x12345678
    ldrh r0, =0x12345678    @读取结果:0x5678
    ldrb r0, =0x12345678    @读取结果:0x78
    @ 前置索引
    ldr r0, [r0, #2]        @从r0+2对应的内存地址中读取内容
    @ 后置索引
    ldr r0, [r0], #2        @从r0中读取内容, r0修改为r0+2
    @ 自索引
    ldr r0, [r0, #2]!       @从r0+2中读取内容, r0修改为r0+2
写内存指令str strh strb
助记: st ===> store 保存
       h ===> half 半字
       b ===> byte 字节
语法格式: 
    普通读写
        str{cond} Rn, [Rm]  保存1个字的内容到Rm对应的内存中
        strh{cond} Rn, [Rm] 保存半字内容到Rm对应的内存中
        strb{cond} Rn, [Rm] 保存1个字节的内容到Rm对应的内存中
        
    内存地址索引方式读写
    1. 前置索引
        str{cond} Rn, [Rm, #4]  保存1个字的内容到Rm+4对应的内存中
        strh{cond} Rn, [Rm, #4] 保存半字内容到Rm+4对应的内存中
        strb{cond} Rn, [Rm, #4] 保存1个字节的内容到Rm+4对应的内存中容

    2. 后置索引
        str{cond} Rn, [Rm], #4  保存1个字的内容到Rm对应的内存中
                                并将Rm的地址修改为Rm + 4
        strh{cond} Rn, [Rm], #4 保存半字内容到Rm对应的内存中
                                并将Rm的地址修改为Rm + 4
        strb{cond} Rn, [Rm], #4 保存1个字节的内容到Rm对应的内存中容
                                并将Rm的地址修改为Rm + 4

    3. 自索引
        str{cond} Rn, [Rm, #4]!  保存1个字的内容到Rm+4对应的内存中
                                 同时将Rm的地址修改为Rm + 4
        strh{cond} Rn, [Rm, #4]! 保存半字内容到Rm+4对应的内存中
                                 同时将Rm的地址修改为Rm + 4
        strb{cond} Rn, [Rm, #4]! 保存1个字节的内容到Rm+4对应的内存中容
                                 同时将Rm的地址修改为Rm + 4

        
功能: 将Rm的值保存到Rn寄存器中
注意: Rm 相当于指针, [Rm] 相当于取出指针所指向地址的值
例:
    ldr r0, =0x40000300     @将地址保存到r0寄存器中
    ldr r1, #0x12345678
    str r1, [r0]            @将寄存器r1的值保存到r0对应的内存中
    strb r1, [r0]           @保存结果 78
    strh r1, [r0]           @保存结果 5678
    @ 前置索引
    str r1, [r0, #4]        @ 保存r1到r0+4对应的内存中
    @ 后置索引
    str r1, [r0], #4        @ 保存r1到r0中, 修改r0为r0+4
    @ 自索引
    str r1, [r0, #4]!       @ 保存r1到r0+4中,修改r0为r0+4
load/store多寄存器内存读写指令
多寄存器写到连续内存指令stm
语法格式: stm{cond} Rn, {寄存器列表}
助记: m->multiple
功能: 将寄存器列表中的内容保存到连续的内存空间中
例:
    stm r0, {r1-r3}
    stm r0, {r1, r5-r7, r9}
    stm r0, {r1, r3, r5}
连续内存读到多寄存器指令ldm
语法格式: ldm{cond} Rn, {寄存器列表}
助记: m->multiple
功能: 将Rn中地址所对应的连续空间的内容保存到寄存器列表中
例:
    ldm r0, {r1-r5}
    ldm r0, {r1, r5-r7, r9}
移位操作指令
逻辑左移指令(最右补0)lsl
语法格式: lsl{cond}{s} Rd, Rn, oprand2
功能: 逻辑左移, 无符号左移, 高位移出, 低位补零
例:
    lsl r0, r1, #3
逻辑右移指令(最左补0)lsr
语法格式: lsr{cond}{s} Rd, Rn, oprand2
功能: 逻辑右移, 无符号数的右移, 低位移出, 高位补零
例:
    lsr r0, r1, #3
算数右移指令(最左补符号位)asr
语法格式: asr{cond}{s} Rd, Rn, oprand2
功能: 算数右移, 有符号数的右移, 低位移出, 高位补符号位
例:
    asr r0, r1, #3
循环右移指令ror
语法格式: ror{cond}{s} Rd, Rn, oprand2
功能: 循环右移, 低位移出, 补到高位
例:
    ror r0, r1, #3
位运算指令
按位与指令and
语法格式: and{cond}{s} Rd, Rn, oprand2
功能: 按位与, 与0清0, 与1不变
例:
    and r0, r1, #FFFFFFEF
按位或指令orr
语法格式: orr{cond}{s} Rd, Rn, oprand2
功能: 按位或, 或1置1, 或0不变
例:
    orr r0, r1, #(1 << 3)
按位抑或指令eor
语法格式: eor{cond}{s} Rd, Rn, oprand2
功能: 按位异或, 异或1取反, 异或0不变
例:
    orr r0, r1, #AAAAAAAA
按位取反指令~
语法格式: ~oprand2
功能: 按位取反
例:
    mov r0, #~0x30
按位清零指令bic
语法格式: bic{cond}{s} Rd, Rn, oprand2
功能: 按位清零, Rn遇到对应oprand2中含有1的位都会被清零
例:
    bic r0, r1, #3
跳转指令
无返回跳转指令b
语法格式: b{cond} 标签
功能: 直接跳转, 不保存返回地址到lr寄存器
例:
    b stop
有返回跳转指令bl
语法格式: bl{cond} 标签
功能: 跳转, 并保存返回地址到lr寄存器中
例:
    bl func_add
    
    func_add:
        @ do add
        mov pc lr
特殊寄存器操作指令
读取状态寄存器指令mrs
语法格式: mrs cpsr oprand2
功能: 读取 cpsr寄存器中的值到寄存器oprand2中
例:
    mrs cpsr r0
写入状态寄存器指令msr
语法格式: msr cpsr oprand2
功能: 将oprand2的值写入到cpsr寄存器中
例:
    msr cpsr r0
栈操作指令
栈的分类
  1. 空栈:当前栈指针指向的空间, 认为没有有效数据, 压栈时覆盖掉此空间
  2. 满栈:当前栈指针指向的空间, 认为存在有效数据, 压栈时先移动栈指针,再压栈
  3. 增栈:压栈时,栈顶指针往高地址移动
  4. 减栈:压栈时,栈顶指针向低地址移动
栈空间的4中操作方式
  1. 满增栈: stmfa ldmfa full ascending
  2. 满减栈: stmfd ldmfd full descending
  3. 空增栈: stmea ldmea empty ascending
  4. 空减栈: stmed ldmed empty descending
压栈指令stmfd stmfa stmed stmea
语法格式: stmfd sp!, {寄存器列表} 	满增式压栈
语法格式: stmfa sp!, {寄存器列表}		满减式压栈
语法格式: stmed sp!, {寄存器列表}		空增式压栈
语法格式: stmea sp!, {寄存器列表}		空减式压栈
功能:将寄存器列表中的数据压入栈中
例:
    stmfd sp!, {r0-r5}		@认为栈顶满,且为低地址, 跳过栈顶, 向高地址依次写入
    stmfa sp!, {r0-r5}		@认为栈顶满, 且为高地址, 跳过栈顶, 向低地址依次写入
    stmed sp!, {r0-r5} 		@认为栈顶空, 且为低地址, 写入栈顶, 并依次向高地址写入
    stmea sp!, {r0-r5}		@认为栈顶空, 且为高地址, 写入栈顶, 并依次向低地址写入
出栈指令ldmfd ldmfa ldmed ldmea
语法格式: ldmfd sp!, {寄存器列表}		满增式出栈
语法格式: ldmfa sp!, {寄存器列表}		满减式出栈
语法格式: ldmed sp!, {寄存器列表}		空增式出栈
语法格式: ldmea sp!, {寄存器列表}		空减式出栈
功能: 出栈数据存入到寄存器列表中
例:
    ldmfd sp!, {r1, r5}		@认为栈顶满,由低向高压栈而来, 所以返回栈顶,向低地址依次出栈
    ldmfa sp!, {r1, r5}		@认为栈顶满, 有高向低压栈而来, 所以返回栈顶,向高地址依次出栈
    ldmed sp!, {r1, r5}		@认为栈顶空, 由低向高压栈而来, 跳过栈顶, 向低地址依次出栈
    ldmea sp!, {r1, r5}		@认为栈顶空, 有高向低压栈而来, 跳过栈顶, 向高地址依次出栈
  • 3
    点赞
  • 43
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

__万波__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值