ARM汇编指令 SUB MOV LDR STR

开启arm汇编学习。

环境介绍:使用的是TI TDA4平台。该平台是基于ARMV8架构,64bit的CPU。

先上一段C代码:

#include <stdio.h>

int main(void)
{
        char ch1 = 10;
        char ch2 = 11;
        ch2 = ch1;
        unsigned short sh1 = 20;
        unsigned short sh2 = 22;
        sh1 = sh2;
        int num1 = 30;
        int num2 = 33;
        num1 = num2;
        long long lnum1 = 40;
        long long lnum2 = 44;
        lnum1 = lnum2;

        return 0;
}

把C代码编译生成汇编代码:

        .arch armv8-a
        .file   "main.c"
        .text
        .align  2
        .global main
        .type   main, %function
main:
.LFB0:
        .cfi_startproc
        sub     sp, sp, #32
        .cfi_def_cfa_offset 32
        mov     w0, 10
        strb    w0, [sp, 31]
        mov     w0, 11
        strb    w0, [sp, 30]
        ldrb    w0, [sp, 31]
        strb    w0, [sp, 30]
        mov     w0, 20
        strh    w0, [sp, 28]
        mov     w0, 22
        strh    w0, [sp, 26]
        ldrh    w0, [sp, 26]
        strh    w0, [sp, 28]
        mov     w0, 30
        str     w0, [sp, 20]
        mov     w0, 33
        str     w0, [sp, 16]
        ldr     w0, [sp, 16]
        str     w0, [sp, 20]
        mov     x0, 40
        str     x0, [sp, 8]
        mov     x0, 44
        str     x0, [sp]
        ldr     x0, [sp]
        str     x0, [sp, 8]
        mov     w0, 0
        add     sp, sp, 32
        .cfi_def_cfa_offset 0
        ret
        .cfi_endproc
.LFE0:
        .size   main, .-main
        .ident  "GCC: (GNU Toolchain for the A-profile Architecture 9.2-2019.12 (arm-9.10)) 9.2.1 20191025"
        .section        .note.GNU-stack,"",@progbits

C代码编译成汇编代码的脚本:

#!/bin/sh

export PATH=${PATH}:/home/CN/qidong.liu/ti/tda4/server/tda4vl/camera_ok/rtos/gcc-arm-9.2-2019.12-x86_64-aarch64-none-linux-gnu/bin

aarch64-none-linux-gnu-gcc -E main.c -o main.i
aarch64-none-linux-gnu-gcc -S main.i -o main.S

对生成的汇编代码做一个简单的解释:


main:
.LFB0:
        .cfi_startproc
        sub     sp, sp, #32        //申请32字节的栈空间。注:本验证发现,栈的大小似乎总是16的整数倍。
        .cfi_def_cfa_offset 32
        mov     w0, 10            //将10保存到寄存器w0里面
        strb    w0, [sp, 31]      //将寄存器w0的内容,保存到栈偏移31字节处。这里是以字节为操作单位。strb的b,表示byte
        mov     w0, 11
        strb    w0, [sp, 30]
        ldrb    w0, [sp, 31]      //将栈偏移31字节处的内容,加载到寄存器w0里面
        strb    w0, [sp, 30]
        mov     w0, 20
        strh    w0, [sp, 28]      //将寄存器w0的内容,保存到栈偏移28字节处。这里是以半字为操作单位。strh的h,表示half word
        mov     w0, 22
        strh    w0, [sp, 26]
        ldrh    w0, [sp, 26]      //将栈偏移26字节处的内容加载到w0寄存器。这里是以半字为操作单位。
        strh    w0, [sp, 28]
        mov     w0, 30
        str     w0, [sp, 20]      //将寄存器w0的内容,保存到栈偏移20字节处。这里是以字为操作单位。str的操作单位和寄存器有关 这里的单位为字
        mov     w0, 33
        str     w0, [sp, 16]
        ldr     w0, [sp, 16]      //将栈偏移16字节处的内容加载到w0寄存器。这里是以字为操作单位。ldr的操作单位和寄存器有关 这里的单位为字
        str     w0, [sp, 20]
        mov     x0, 40            //x0和w0寄存器为同一个寄存器,w0寄存器为x0寄存器的低32位
        str     x0, [sp, 8]       //将寄存器x0的内容保存到栈偏移8字节处。这里是以双字为操作单位。str的操作单位和寄存器有关 这里的单位为双字
        mov     x0, 44
        str     x0, [sp]
        ldr     x0, [sp]          //将栈偏移0字节处的内容加载到x0寄存器。这里是以双字为操作单位。ldr的操作单位和寄存器有关 这里的单位为双字
        str     x0, [sp, 8]
        mov     w0, 0
        add     sp, sp, 32
        .cfi_def_cfa_offset 0
        ret
        .cfi_endproc

上面对部分指令做了一个简单的解释。下面进行一点扩展。

mov指令:

mov x0, 123
将立即数123保存到寄存器x0里面

mov x1, x2
将寄存器x2里面的内容保存到寄存器x1里面

注:ARM架构中,内存单元上的数据不允许被直接操作。因此mov指令作用于寄存器与立即数直接的操作。

ldr指令:将内存上的内容加载到寄存器里面

ldr x0, [x1]
将x1寄存器里面的内容作为内存地址,把该内存地址的值加载到x0寄存器里面

注:ldr指令还有其他一些类型,如:ldrb、ldrh
ldrb:操作单位为字节
ldrh:操作单位为半字
ldr:操作单位和寄存器类型有关。w0这一类的寄存器操作单位就是字。x0这一类的寄存器操作单位就是双字。

str指令:将寄存器的内容保存到内存上面去

str x0, [x1]
将x0寄存器里面的内容保存到x1寄存器里面的值的对应的内存空间。
举例:str x0, [x1]    //x0=123    x1=456789
将123保存到内存地址为456789的地址处。

str x0, [x1], #8
将x0寄存器里面的内容保存到x1寄存器里面的值的对应的内存空间。同时x1寄存器的内容更新为x1+8

str也有一些其他类似指令:strb、strh。这些指令的操作单位和ldr那一类指令类似

add指令:加法指令

add x0, x1, x2
x0=x1+x2

add x0, x1, #123
x0=x1+123

注:add指令操作的对象也是寄存器和立即数。似乎不能直接操作内存。

sub指令:减法指令

sub x0, x1, x2
x0=x1-x2

sub x0, x1, #123
x0=x1-123

注:sub指令操作的对象也是寄存器和立即数。似乎不能直接操作内存。

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

monkey_llll

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

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

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

打赏作者

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

抵扣说明:

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

余额充值