arm汇编(c内嵌汇编及c和汇编互调)

C语言编译成汇编:

arm-linux-gcc -S test.c -o test.S

 

C语言编译成可执行文件:

arm-linux-gcc test.c -o test

 

多个文件编译链接:

arm-linux-gcc –c main.c –o main.o

arm-linux-gcc –c abc.S –o abc.o

arm-linux-gcc main.o abc.o –o test.o

 

汇编编译两种方式:

arm-linux-as test.S -o test.o

arm-linux-gcc –c test.S –o test.o

 

ARM裸机程序编译:

arm-linux-gcc -c start.S -o start.o

arm-linux-ld -Ttext=0x40000000 start.o -o start.elf

arm-linux-objcopy -I elf32-littlearm -O binary start.elf –o start.bin

 

查看代码地址信息:

arm-linux-objdump -h test

 

ARM反汇编:

arm-linux-objdump -D elf_file > dis_file

 

一、arm内嵌汇编

#include <stdio.h>

int main(void){

int a = 88;

__asm__ __volatile__(

                   "mov r0, %1\n"

                   "mov r1, #1\n"

                   "add %0, r0, r1\n"

                   : "=r" (a)

                   :"r" (a)

                   : "r0", "r1"

         );

         printf("a = %d\n",a);

         return 0;

}

有些知识:

a) __asm__(下划线每次两根):表示嵌入汇编。__volatitle__:表示编译不优化。

b) c语言中我们是这样定义字符串的char *str = “Hello, world”;但同时我也可以这样定义:char *str = “Hello,” “world”;,这样同样是表示一个字符串。内嵌汇编中通过\n来分开每条指令,如:”mov r0,r1\nmov r1,r2”。显然这样连着不方便阅读,我想要一条指令一行,这样好些,有两种写法:

1)”mov r0,r1\n  \

mov r1,r2”

就是用\作为连字符

2)”mov r0,r1\n”

  “mov r1,r2”

  就是和上面说的c中定义字符串的第二种形式。

 

冒号后面相关含义:

: "=r" (a):内嵌汇编输出部分(通过=r来判断为输出)

:"r" (a):内嵌汇编输入部分(通过r来判断输入)

: "r0", "r1":需要保护的寄存器(破坏部分)

用占位符来引用输入输出变量,按位置从%0、%1以此类推,如:这里输入部分a在前面即它为%0,输出a即为%1。

再比如::”=r” (a),”=r”b

                   :”r” (a)

则顺序为%0、%1、%2

除了用%n之外还可以用标号:

:[a] “=r” (a)

:[b] “r” (b)

使用:mov %[b],%[a]

 

 

二、汇编调用C函数

汇编文件main.S

         .section .text

         .global main

main:

         mov ip, sp

         stmfd sp!, {fp, ip, lr, pc}

         sub fp, ip, #4

        

         bl abc

        

         ldr r0, =str

         mov r1, #'a'

         strb r1, [r0]

        

         bl printf

        

         sub sp,fp ,#12

         ldmfd sp, {fp, sp, pc}

        

         .section .data

        

str:

         .asciz "hello world.\n"

 

str1:

         .ascii "hello world.\n0"

 

         .comm l1, 10000

        

l2: .space 1000

 

C文件abc.c

void abc(void)

{

         printf("hello, c file\n");

}

 

三、C调用汇编函数

C文件main.c

#include <stdio.h>

extern void abc(void);

void main(void)

{

  printf("start call asm fun\n");

  abc();

  printf("end call asm fun\n");

}

汇编文件abc.S

         .global abc

abc:

         mov ip, sp

         stmfd sp!, {fp, ip, lr, pc}

         sub fp, ip, #4

        

         adr r0, str

         bl printf

        

         b next

        

str:

         .asciz "hello, s file\n"

        

         .align 2

next:

         sub sp,fp ,#12

         ldmfd sp, {fp, sp, pc}

 

其中,这个C和汇编的互调还是不太理解,先做个笔记先。

posted on   大梦烟云  阅读(2049)  评论(0编辑  收藏  举报

努力加载评论中...

导航

点击右上角即可分享
微信分享提示