zoukankan      html  css  js  c++  java
  • arm汇编笔记

    ARM汇编(非虫笔记)

    1.ARM汇编的目的:

    分析elf文件的需要。

    2.原生程序生成过程。

    (1)预处理,编译器处理c代码中的预处理指令。

    gcc -E hello.c -o hello.i

    (2)编译 gcc编译器首先要检查代码的规范性,以及是否有语法错误,在检查无误之后,gcc编译把代码翻译成ARM汇编语言的代码。

    gcc -S hello.i -o hello.s

    (3)汇编,gcc编译器会挑用汇编器将汇编代码汇编成二进制目标文件。

    gcc -c hello.s -o hello.o

    (4)链接,这个阶段会调用链接器将二进制的目标文件链接成android平台可执行的ARM远程程序。

    gcc hello.o -o hello

    3.ARM知识了解

    (1)与JAVA的区别:

    ARM汇编语言是一门"低级"语言可以和系统的底层相互沟通。

    (2)ARM汇编语言编写的程序运行速度快,占用内存少

    (3)缺点是编写的代码难懂,难以维护。

    (4)ARM汇编语言,c语言能实现的ARM汇编语言都能实现。

    (5)ARM具有31个通用寄存器,6个状态寄存器

    (6)ARM处理器支持其中运行模式。

    1. 用户模式:ARM处理器正常的程序执行状态。

    2.快速中断模式:用于高速数据传输或通道处理。

    3.外部中断模式:用于通用的中断处理。

    4.管理模式:操作系统使用的保护模式。

    5.数据访问终止模式:当数据或指令预取终止时进如该模式,可用于模拟存储及存储保护。

    6.系统模式:运行具有特权的操作系统任务。

    7.未定义指令中止模式:当未定义的指令执行时进入该模式。

    4.ARM汇编语言程序结构

    (1)处理器架构定义

    .arch armv5te @处理器架构
    .fpu softvfp  @协处理器类型
    .ebi_attribute 20,1 @接口属性
    .ebi_attribute 21,1
    .ebi_attribute 23,1
    .ebi_attribute 24,1
    .ebi_attribute 25,1
    .ebi_attribute 26,1
    .ebi_attribute 30,1
    .ebi_attribute 18,1

    .arch指定了ARM处理器架构。

    .armv5te表示本程序在armv5te架构处理器上运行。

    .fpu指定了协处理器的类型。

    softvfp表示使用浮点运算库来模拟协处理运算。

    .ebi_attribute 指定了一些接口属性。

    (2)段定义:

    .section 定义只读数据,属性是默认
    .text 定义了代码段。

    因为之前读过了8086王爽的汇编,所以对段的理解很轻松。

    (3)注释与标号

    注释方法:/.../多行注释,@单行注释

    标号:<标号名>:

    eg:
        loop:
        ...
        end loop

    标号和8086汇编很类似。

    (4)汇编器指令

    程序中所有以"."开头的指令都是汇编指令,他们不属于ARM指令集。

    部分会汇编器指令:

    .file: 制定了源文件名。
    .align:代码对其方式。
    .ascii:声明字符串。
    .global:声明全局变量。
    .type:指定符号的类型。

    (5)字程序与参数传递。

    声明函数的方法:

    .global 函数名
    .type  函数名,%function
    函数名:
        <...函数体...>
    声明一个实现两个数相加的函数的代码
    .global MyAdd
    .type MyAdd,&function
    MyAdd:
        add r0,r0,r1 
        mov pc,lr 

    ARM汇编规定:R0-R3这4个寄存器用来传递函数调用的第1到第4个参数,超过的参数通过堆栈来传递。

    (6)ARM处理器寻址方式

    1.立即寻址。

    mov R0,#1234 @# z作为前缀,表示16进制时以"0x"开头

    2.寄存器寻址。

    mov R0,R1

    3.寄存器移位寻址。

    五种移位操作:

    (1)LSL:逻辑左移,移位后寄存器空出的低位补0
    (2)LSR:逻辑右移,移位后寄存器空出的高位补0
    (3)ASR:算数右移,移动过程中符号位不变。如果操作数是整数,则移位后空出的高位补0,否则补1
    (4)ROR:循环右移,移位后移出的低位填入移位空出的高位。
    (5)RRX:带扩展的循环右移,操作数右移移位,移位空出的高位用C标志的值填充。
    eg:

    mov R0,R1,LSL #2

    4.寄存器间接寻址

    LDR R0,[R1]

    5.基址寻址

    LDR R0,[R1,#-4]

    6.多寄存器寻址

    LDMIN R0,{R1,R2,R3,R4}
    LDM 是数据加载命令
    指令的后缀IA表示每次执行完成加载操作后R0寄存器的值自增1
    ARM中,字表示的是一个32位。
    R1=[R0]
    R2=[R0+#4]
    R3=[R0+#8]
    R4=[R0+#12]
    Ps:这里+#4的原因是因为32位占4个字节。

    7.堆栈寻址。

    STMFD SP!,{R1-R7,LR} 入栈,多用于保存子程序“现场”
    LDMFD Sp!,{R1-R7,LR} 出栈,多用于回复子程序的现场

    8.块拷贝寻址。

    块拷贝可实现连续地址数据从存储器的某一位置拷贝到另一位置。

    LDMIN R0!,{R1-R3} @从寄存器指向的存储单元中读取3个字到R1-R3寄存器。

    9.相对寻址 。

    相对寻址一程序计数器PC的当前值为基地址,指令中的地址标号作为偏移量,将两者相加之后得到的操作数的有效地址。

  • 相关阅读:
    H5页面富文本展示图片之间存在空隙
    如何关闭eslint语法校验
    K8S service详解
    vim添加或删除多行注释
    K8S 弹性伸缩
    Load高问题排查
    Dockerfile CMD和ENTRYPOINT
    nginx配置
    sed命令
    Pod排错指南
  • 原文地址:https://www.cnblogs.com/lemaden/p/10381511.html
Copyright © 2011-2022 走看看