您的位置:首页 > 其它

ARM汇编语言学习笔记(一)---ARM汇编的程序结构

2016-11-17 15:21 363 查看

0x00 用到的书籍

《Android软件安全与逆向分析》第六章

0x01 原生程序的生成过程

笔者是在Linux环境下测试的,详细过程见书中说明

需要编译的C语言代码

#include <stdio.h>

int main(int argc, char* argv[]){
printf("Hello ARM!\n");
return 0;
}


预处理,生成hello.i文件

gcc -E hello.c -o hello.i


编译

gcc -S hello.i -o hello.s


汇编,生成二进制目标文件

gcc -c hello.s -o hello.o


链接,生成hello可执行文件

gcc hello.o -o hello




0x02 完整ARM汇编结构

下面打开生成的.文件

.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               @声明对齐方式2^2=4字节
.LC0:                      @标号LC0
.ascii  "Hello ARM!\000"@声明字符串
.text                    @声明代码段
.align  2               @声明对齐方式4字节
.global main            @全局符号main
.type   main, %function @main类型为函数
main:                        @标号main
@ args = 0, pretend = 0, frame = 8
@ frame_needed = 1, uses_anonymous_args = 0
stmfd   sp!, {fp, lr}   @将fp,lr压入堆栈
add fp, sp, #4           @初始化fp寄存器,设置栈帧,用于访问局部变量
sub sp, sp, #8           @开辟栈空间
str r0, [fp, #-8]        @保存第一个参数
str r1, [fp, #-12]       @保存第二个参数
ldr r3, .L3              @取标号.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


0x03 处理器架构定义

.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


0x04 段定义

本例子中定义了三个段

如下:

.section    .rodata                           @声明只读数据
.text                                      @定义了代码段
..section   .note.GNU-stack,"",%progbits  @保护代码,禁止生成可执行堆栈。


0x05 注释与标号

单行注释用@表示,例如

@声明只读数据


多行注释用/* */

0x06 汇编器指令

程序中所有以点开头的都是汇编器指令,就是给汇编器读的指令,不属于ARM指令集

.flie:指定了源文件名。手写可忽略

.align:指定了代码对齐方式你后面跟的是2的次方

.ascii:声明字符串

.global:声明全局符号。全局符号是指在本程序外可访问的符号。

.type:指定符号的类型,“.type main,%function”表示main为函数

.word: 用来存放地址。

.size:设定指定符号的大小。“.size main,.-main”中的”.”表示当前地址,减去main符号的地址为整个main函数的大小。

.ident:编译器标识,无实际意义。

0x07 子程序与参数传递

函数声明方法

.global 函数名
.type    函数名,“%function”
函数名:
<函数体>


实例

.global MyAdd
.type MyAdd,%function
MyAdd:
ADD r0,r0,r1  @两个数相加
MOV pc,lr     @ 函数返回


ARM参数传递规定(重要)

R0-R3这4个寄存器用来传递函数调用的第1到4个参数,超出的通过堆栈来传递,R0同时用来存放函数调用的返回值。由函数调用方来平衡堆栈。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  arm