zoukankan      html  css  js  c++  java
  • 【基于Android的ARM汇编语言系列】之三:ARM汇编语言程序结构

    作者:郭嘉
    邮箱:allenwells@163.com
    博客:http://blog.csdn.net/allenwells
    github:https://github.com/AllenWell

    【基于Android的ARM汇编语言系列】章节列表

    【基于Android的ARM汇编语言系列】之中的一个:ARM汇编语言开篇
    【基于Android的ARM汇编语言系列】之二:C/C++程序生成ARM汇编程序的过程分析
    【基于Android的ARM汇编语言系列】之三:ARM汇编语言程序结构
    【基于Android的ARM汇编语言系列】之四:ARM处理器的寻址方式
    【基于Android的ARM汇编语言系列】之五:ARM指令集与Thumb指令集
    【基于Android的ARM汇编语言系列】之六:NEON指令集与VFP指令集

    Android平台的ARM汇编是GNU ARM汇编格式。使用的汇编器是GAS(GNU Assembler),GAS有自己的一套语法结构。

    具体的内容能够查阅GAS语法结构官方手冊

    我们先来看一个完整的ARM汇编程序:

    C代码:

    #include <stdio.h>
    
    int main(int argc, char* argv[]){
        printf("Hello ARM!
    ");
        return 0;
    }
    

    相应的汇编代码:

        .arch armv5te
        .fpu softvfp
        .eabi_attribute 20, 1
        .eabi_attribute 21, 1
        .eabi_attribute 23, 3
        .eabi_attribute 24, 1
        .eabi_attribute 25, 1
        .eabi_attribute 26, 2
        .eabi_attribute 30, 6
        .eabi_attribute 18, 4
        .file   "hello.c"
        .section    .rodata
        .align  2
    .LC0:
        .ascii  "Hello ARM!00"
        .text
        .align  2
        .global main
        .type   main, %function
    main:
        @ args = 0, pretend = 0, frame = 8
        @ frame_needed = 1, uses_anonymous_args = 0
        stmfd   sp!, {fp, lr}
        add fp, sp, #4
        sub sp, sp, #8
        str r0, [fp, #-8]
        str r1, [fp, #-12]
        ldr r3, .L3
    .LPIC0:
        add r3, pc, r3
        mov r0, r3
        bl  puts(PLT)
        mov r3, #0
        mov r0, r3
        sub sp, fp, #4
        ldmfd   sp!, {fp, pc}
    .L4:
        .align  2
    .L3:
        .word   .LC0-(.LPIC0+8)
        .size   main, .-main
        .ident  "GCC: (GNU) 4.4.3"
        .section    .note.GNU-stack,"",%progbits
    

    以下分部分介绍这段代码的结构。

    一 处理器架构定义

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

    1.1 处理器架构

    .arch指定了ARM处理器架构。armv5te表示本程序的代码能够执行在armv5te架构的处理器上执行。

    1.2 协处理器类型

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

    softvfp表示使用浮点数运算库来模拟协处理器运算。还能够用vfpv2、vfpv3来指定自带的协处理器。

    1.3 接口属性

    .eabi_attrbute指定了一些接口。

    EABI(Embedded Application Binary Interface)嵌入式应用二级制接口是ARM指定的一套接口规范。Android系统实现了它。

    二 段定义

        .file   "hello.c"
        .section    .rodata
        .align  2
    .LC0:
        .ascii  "Hello ARM!00"
        .text
        .align  2
        .global main
        .type   main, %function
    main:
        @ args = 0, pretend = 0, frame = 8
        @ frame_needed = 1, uses_anonymous_args = 0
        stmfd   sp!, {fp, lr}
        add fp, sp, #4
        sub sp, sp, #8
        str r0, [fp, #-8]
        str r1, [fp, #-12]
        ldr r3, .L3
    .LPIC0:
        add r3, pc, r3
        mov r0, r3
        bl  puts(PLT)
        mov r3, #0
        mov r0, r3
        sub sp, fp, #4
        ldmfd   sp!, {fp, pc}
    .L4:
        .align  2
    .L3:
        .word   .LC0-(.LPIC0+8)
        .size   main, .-main
        .ident  "GCC: (GNU) 4.4.3"
        .section    .note.GNU-stack,"",%progbits

    ARM中段的定义格式例如以下所看到的:

    .section name , "flags", %type, flag_specific_arguments
    • name:段名
    • flags:段的属性。如读、写和可执行等。
    • type:段的类型,如progbits表示段中含有数据。note表示段中包括的数据并不是程序本身使用。
    • flag_specific_arguments:指定了一些平台相关的參数。

    三 凝视与标号

    GNU ARM支持两种凝视加入方式。

    /* */型凝视

    /* args = 0, pretend = 0, frame = 8 */
    /* frame_needed = 1, uses_anonymous_args = 0 */

    @型凝视

    @ args = 0, pretend = 0, frame = 8
    @ frame_needed = 1, uses_anonymous_args = 0

    四 汇编器指令

    .file   "hello.c"
        .section    .rodata
        .align  2
    .LC0:
        .ascii  "Hello ARM!00"
        .text
        .align  2
        .global main
        .type   main, %function

    程序中全部以.开头的指令都是汇编器指令,汇编器指令是与汇编器相关的,它们并不属于ARM指令集。

    • .file:指定源文件名称。
    • .align:指定代码的对齐方式。后面跟的数值是2的次数方。
    • .ascii:声明字符串。
    • .global:声明全局符号,全局符号是指在本程序外能够訪问的符号,
    • .type:指定符号的类型。
    • .word:用来存放地址值。
    • .size:设置指定符号的大小。

    • .ident:编译器标识。无实际用途。

    五 子程序与參数传递

    子程序在代码表示一个独立的功能。非常多时候。子程序和代码是同样的概念。在汇编中声明函数的方式例如以下所看到的:

    .global 函数名
    .type 函数名 %Function
    函数名:
        ...
        函数体
        ...

    那么函数调用过程中。參数传递的方式例如以下所看到的:

    ARM汇编中规定:R0~R3这4个寄存器分别用来传递函数调用的第1到第4个參数。超出的參数通过堆栈来传递。R0寄存器用来存放函数调用的返回值。被调用的函数在返回前无需恢复这些寄存器的内容。

  • 相关阅读:
    Winpcap网络开发库入门
    主机字节序与网络字节序的转换
    WORD与DWORD
    TCP/IP各种数据包结构体
    解析IPV4报文 和IPV6 报文的 checksum
    TCP头校验和计算算法详解
    第九次作业:DFA最小化,语法分析初步
    第八次作业:非确定的自动机NFA确定化为DFA
    第七次:正规式、正规文法与自动机
    第六次作业:正规文法与正规式
  • 原文地址:https://www.cnblogs.com/yxysuanfa/p/7338409.html
Copyright © 2011-2022 走看看