arm汇编如何编译 | 为什么学古董语言?
来源:互联网 发布:广西安全知识网络竞赛 编辑:程序博客网 时间:2024/06/10 16:42
本文主要讲解如何写一个gnu arm汇编程序,并且编译,使其在安卓手机上运行起来。
(一)为什么学arm汇编?
如果允许在使用时才去学的话,任何东西都不必提前学习。而“用时才学”的情况是经常存在的,也是有道理的,你的时间跟精力不应该放在一些现在用不上的知识与技能上(以后可能用上?那以后出现再说,先解决已经出现的或即将出现的问题;如果没有问题,那就开心玩耍去吧)。同样,学习arm汇编,最好是因为你“在做”的事情需要用到这些知识与技能,比如要翻译一段别人的汇编代码,比如需要做一些逆向的修改汇编代码的工作,比如需要看懂程序崩溃时的汇编代码,等等。而至于装逼,也是一个理由(装逼也可能让你有一定的大局观)。
(二)怎么写一个hello world?
用你熟悉的编辑器写就好,保存为.s文件。至于gnu arm asm的语法,查一下手册与例子吧。
比如say hello:
.data msg: .asciz "hello, gnu asm\n" len = . - msg .text .global main main: push {r0,r1,r2,lr} ldr r1, =msg @ address mov r0, #1 @ stdout ldr r2, =len @ length mov %r7, $4 /* write is syscall #4 */ swi $0 /* invoke syscall */ pop {r0,r1,r2,pc}
再比如求和:
.data msg: .asciz "sum=%d\n" .text sum: push {lr} mov r2, r0 mov r3, r1 add r0, r2, r3 pop {pc} .global main main: push {r0, r1, r2, lr} mov r0, #100 mov r1, #120 bl sum mov r1, r0 ldr r0, =msg bl printf pop {r0, r1, r2, pc}
(三)怎么编译一个汇编程序?
这里的目标是在android手机上运行。
交叉编译arm汇编源文件
最终要在android机子上运行,那执行文件的格式就是elf,所以要编译成elf格式的文件。
在mac上,要使用交叉编译工具(即编译出另一个平台用的程序的工具),这个工具可以是:arm-linux-androideabi-gcc(目录比如:toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/),但在编译时(比如直接gcc -o test test.c)会遇到识别不了头文件(如stdio.h)的情况,原因是没有指定头文件的目录。
解决办法:使用编译工具链。
编译工具链,就是适用于某个场景(比如生成给某个平台用的执行文件)的编译(或链接等)环境,包括了编译时需要使用到的头文件等。
创建这个编译环境,需要使用ndk里面的make-standalone-toolchain.sh脚本。
最终的编译脚本如下:
#!/bin/bash# toolchainTOOLCHAIN=~/asmtoolchainSYSROOT=$TOOLCHAIN/sysroot/ANDROID_NDK_ROOT=/Users/sky/Documents/android-ndk-r10dNDK_PATH=$ANDROID_NDK_ROOTMIN_PLATFORM=android-8TOOLCHAIN_VER=arm-linux-androideabi-4.8OUT_NAME=helloasmOBJS=helloasm.sif [ ! -d $SYSROOT ]; then$NDK_PATH/build/tools/make-standalone-toolchain.sh --platform=$MIN_PLATFORM --install-dir=$TOOLCHAIN --toolchain=$TOOLCHAIN_VERfiPATH=$TOOLCHAIN/bin:$PATHCC=arm-linux-androideabi-gcc#LD=arm-linux-androideabi-ld#AR=arm-linux-androideabi-ar$CC --sysroot=$SYSROOT -o $OUT_NAME $OBJS
以上编译出的执行文件,是elf格式(file helloasm可查看)。
(四)运行执行文件
拷贝执行文件(比如helloasm)到android手机的/data目录下可以运行(先adb push到/sdcard/,再adb shell到手机并拷贝到/data,再chmod 777 helloasm,之后就可以运行)。
(五)反汇编最终的执行文件
把编译出来的执行文件,再反汇编一下,看看跟源文件有多大的差别。
比如把上面求和的执行程序,用hopper反汇编后,可以看到这样的代码(部分):
sum: @ args = 0, pretend = 0, frame = 8 @ frame_needed = 1, uses_anonymous_args = 0 @ link register save eliminated. str fp, [sp, #-4]! add fp, sp, #0 sub sp, sp, #12 mov r3, #10 str r3, [fp, #-8] mov r3, #3 str r3, [fp, #-12] ldr r2, [fp, #-8] ldr r3, [fp, #-12] add r3, r2, r3 mov r0, r3 sub sp, fp, #0 @ sp needed ldr fp, [sp], #4 bx lr .size sum, .-sum .section .rodata .align 2.LC0: .ascii "%d\012\000" .text .align 2 .global main .type main, %functionmain: @ args = 0, pretend = 0, frame = 16 @ frame_needed = 1, uses_anonymous_args = 0 stmfd sp!, {fp, lr} add fp, sp, #4 sub sp, sp, #16 str r0, [fp, #-16] str r1, [fp, #-20] bl sum(PLT) str r0, [fp, #-8] ldr r3, .L5.LPIC0: add r3, pc, r3 mov r0, r3 ldr r1, [fp, #-8] bl printf(PLT) mov r3, #0 mov r0, r3 sub sp, fp, #4 @ sp needed ldmfd sp!, {fp, pc}
是不是有对应的模样?
写几个小程序,只是熟悉一下asm的一些基础概念(看起来就像在玩),而对于实战,还是要靠信息收集与分析。
- arm汇编如何编译 | 为什么学古董语言?
- 如何学arm
- 为什么学C语言
- 为什么ARM的启动代码是汇编?
- 每天学点ARM汇编 (ARMv4/v5版本汇编) ()
- 为什么大家都要喜欢学ARM?
- 如何学arm linux嵌入式
- 如何学arm linux嵌入式
- VS2005混合编译ARM汇编代码
- 转:VS2005混合编译ARM汇编代码
- arm汇编文件编译以及代码查看
- cmd下编译执行arm汇编文件
- 为什么要学C语言
- 为什么要学c语言
- 为什么要学c语言
- 为什么要学C语言
- c语言编译汇编过程
- GNU ARM汇编--(二)汇编编译链接与运行
- LeetCode之Valid Parentheses
- JDK和JRE的区别
- 如何快速转载CSDN中的博客
- Java菜鸟面试突破系列之java虚拟机
- HTML5表单元素的新特性
- arm汇编如何编译 | 为什么学古董语言?
- 加密gogogo
- Linux系统selinux的初级管理
- OpenJudge百炼-1833-排列-C语言-模拟
- Redhat 6.5 x64升级SSH到OpenSSH_7.5p1
- sh和bash的区别
- C++笔试题 String类的实现 详细
- [leetcode] 78. Subsets
- HDOJ2037 今年暑假不AC (贪心,区间调度)