GUN arm汇编不能像MASM那样支持类C那样的函数写法. 也不支持结构体, 所以注定了GUN汇编不能像MASM那样写大型的程序, 不能像Windows下面那样, 用MASM来写较大型的程序, 所以用C和汇编联合成了一个妥协的办法. 所以这篇写一点GCC和和GUN汇编联合的问题.

联合的话,我们直接可以使用ndk-build进行编译了, 不用再输入arm-linux-androideabi-as.exe这么长的命令. 另外一个调试也可以使用ida来调试了. 最近ida 6.5 泄露出来了, 可以很方便的调试android的arm汇编代码, 不用再用gdb进行调试了. gdb调试真恶心.

既然用ndk-build来编译, 那么直接复制ndk下面的samples test-libstdc++项目出来就好. 这个项目还是和Java没有半毛钱关系. 编译出来的文件是一个elf文件. 修改test-libstdc++的 Android.mk 加入LOCAL_ARM_MODE := arm 表示使用arm指令, 不要使用thumb指令. 然后修改下模块名称再修改下LOCAL_SRC_FILES源文件的名称. 这里有两个源文件ArmC.c和Assembly.S一个C语言文件和一个汇编文件.

# A simple test for the minimal standard C++ library #

I want ARM, not thumb.

LOCAL_ARM_MODE := arm

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS) LOCAL_MODULE := ArmC LOCAL_SRC_FILES := ArmC.c Assembly.S include $(BUILD_EXECUTABLE)

然后C语言是源文件是这样的 ArmC.c

1
2
3
4
5
6
#include <stdio.h>

int main(void)
{	
    printf( "multiplication: %d\\r\\n", multiplication( 10, 20 ));
}

Assembly.S汇编文件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
	.arch armv5te
	.fpu softvfp

	.data
msg:	.ascii		"hello world!\\r\\n"
len= . - msg

	.text

.globl 		multiplication
.type		multiplication, %function

multiplication:
	stmfd	sp!, {fp, ip, lr}

	push 	{r0}

	mov 	r0, $1
	ldr 	r1, =msg
	ldr 	r2, =len
	mov 	r7, $4
	swi 	$0					// 打印 hello world

	pop		{r0}

	mov 	r4, r0, asl #4		// 左移4位

	mov 	r3, r0, asl $3		// 这样也可以
	add 	r0, r3, r0, asl #1	

	ldmfd 	sp!, {fp, ip, lr}
	bx 		lr

.size		multiplication, . - multiplication

然后使用ndk-build, 然后使用Ida 进行调试. 关于怎么用ida进行android调试的网上也有很多代码. 这边就不展开了. 上图吧

20140829170841

参考链接:

http://www.eggwall.com/2011/09/android-arm-assembly-calling-assembly.html

http://blog.sina.com.cn/s/blog_64d0d0f70101lseu.html