GNU ARM汇编--(二)汇编编译链接与运行

原创 2012年04月26日 22:28:46

     GNU的汇编器是GNU Tools的一部分,可以用来ARM的汇编语言源代码编译为二进制文件.关于GNU汇编器的介绍可以搜索《GNU Assembler Manual》.这里我们只是做一个简短的介绍,对GNU汇编器有一个大概的认识,同时通过两个例子了解一下GNU ARM汇编.

     给出一个模板文件:

    .text                                               ; Executable code follows
_start: .global _start                                  ; "_start" is required by the linker
    .global main                                        ; "main" is our main program
    b main                                              ; Start running the main program
main:                                                   ; Entry to the function "main"
; Insert your code here
    mov pc,lr                                           ; Return to the caller
    .end
      汇编器的使用:

      一种汇编器是arm-elf-as,一种是arm-linux-as之类的,这两种汇编器是有细微区别.但是一般做开发,半导体厂商都会提供特定的编译器,用那个编译器应该是没错的,而且优化效果应该是最优的,毕竟是芯片公司提供的嘛.他们对体系架构最了解,很清楚的知道怎么去优化.而我们一般的开发者也可以了解处理器的体系架构和嵌入式系统的系统的特征来对汇编代码和c代码做优化.

      编译过程:

      arm-elf-as -marm7tdmi --gdwarf2 -o filename.o filename.s

      -marm7tdmi是指定CPU,arm7tdmi是属于ARMv4T的,一般来说同是ARMv4T应该是兼容的.

      --gdwarf2是表示包含debug信息.

      链接过程:

      arm-elf-ld -o filename.elf filename.o

      和UNIX系统编程一样,我们可以根据上面的步骤写makefile,然后make一下.

      具体ARM的指令集,伪指令就不写了,资料很多.

      下面举两个ARM汇编的实例,一个是裸机下的蜂鸣器(简单的控制GPIO而已,比流水灯还简单),一个是ARM linux下的"hello world"(利用系统调用来实现的).

       蜂鸣器的例子如下:

       beep.lds  beep.S  Makefile  start.S

      start.S:

.text
.global _start
_start:
	ldr     r3, =0x53000000     @ WATCHDOG寄存器地址
	mov     r4, #0x0                     
	str   r4, [r3]              @ 写入0,禁止WATCHDOG,否则CPU会不断重启

	ldr     sp, =1024*2         @ 设置堆栈,注意:不能大于4k, 因为现在可用的内存只有4K
                                        @ nand flash中的代码在复位后会移到内部ram中,此ram只有4K
	bl      _main                @ 跳转到main函数
halt_loop:
	b       halt_loop

      beep.S

.equ    GPBCON,   0x56000010  
.equ    GPBDAT,   0x56000014  

.global _main  
_main: 
	ldr r0,=GPBCON

	ldr r1,=0x1
	str r1, [r0]
loop:

	ldr r2,=GPBDAT
	ldr r1,=0x1
	str r1,[r2]
	bl delay

	ldr r2,=GPBDAT
	ldr r1,=0x0
	str r1,[r2]
	bl delay

	b loop

delay:
	ldr r3,=0x4ffffff

delay1:
	sub r3,r3,#1

	cmp r3,#0x0

	bne delay1

	mov pc,lr
.end

      beep.lds
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)

SECTIONS{
    . = 0x33000000;
    .text : {
        *(.text)
        *(.rodata)
    }

    .data ALIGN(4): {
        *(.data)
    }

    .bss ALIGN(4): {
        *(.bss)
    }
}

       makefile:

CROSS =  arm-linux-
CFLAGS = -nostdlib

beep.bin: start.S beep.S
	${CROSS}gcc $(CFLAGS) -c -o start.o start.S
	${CROSS}gcc $(CFLAGS) -c -o beep.o beep.S
	${CROSS}ld -Tbeep.lds start.o beep.o -o beep.elf
	${CROSS}objcopy -O binary -S beep.elf beep.bin
	rm -f  *.o


clean:
	rm -f *.elf *.o
	rm -f beep.bin

        编译后将beep.bin文件烧写到dram中,就可以听到声音了.虽然可以运行了,但还是有两个疑问:

        1.lds编译链接文件的写法和技巧    //后续要继续追

        2.elf文件的格式        //elf格式是比较新的可执行文件格式,目前在很多OS上都是用这种格式.这个格式可以在有操作系统的情况下直接运行,但是对于裸机的情况,必须对elf文件                                                做objcopy处理        后续也要继续追


        hello world的例子如下:

        helloworld.S:

.data
	msg:  .asciz  "hello, world\n"

.text
       .align  2
       .global _start
_start:
       ldr     r1, =msg         @ address
       mov     r0, #1          @ stdout
       mov     r2, #13         @ length
       swi     #0x900004       @ sys_write
       mov     r0, #0
       swi     #0x900001       @ sys_exit
       .align  2

       makefile:

all:
	arm-linux-as helloworld.S -o helloworld.o
	arm-linux-ld  helloworld.o -o helloworld

        将elf文件放到跑有linux的arm板子中,运行就输出hello world.也可以在ubuntu中qemu-arm helloworld模拟.

        对比x86下同样用系统调用来输出hello world的程序:

.data
	msg: .string "hello\n"
	len = . - msg
.text
.global _start

_start:
	nop
	movl $len, %edx
	movl $msg, %ecx
	movl $1, %ebx
	movl $4, %eax
	int $0x80

	movl $0, %ebx
	movl $1, %eax
	int $0x80

           它们有几点不同:

            1.arm是用swi指令来进行软中断,陷入内核态来实现系统调用的.而x86是用int $0x80

            2.x86的系统调用号是用eax寄存器表示的,是第一个参数.而arm的swi直接带有系统调用号,0x900004是0x900000+4,其中0x900000是base.


            根据google,做了上面的总结,对GNU ARM汇编有了认识,并且对系统调用软中断,中断处理,uboot异常向量表等等有了探究的欲望,也对elf格式和编译链接有了兴趣,根据自己的方向和精力,后续对这些内容做一个或深或浅的学习.

linux平台学x86汇编(四):从“hello world!”开始

【版权声明:尊重原创,转载请保留出处:blog.csdn.net/shallnet,文章仅供学习交流,请勿用于商业用途】         汇编语言程序由定义好的段构成,每个段有各自的目的。三个最常...
  • gentleliu
  • gentleliu
  • 2015年05月06日 23:56
  • 5040

ARM编译工具

ARM Compilation Tools ARM编译工具就是使用广为人知的ARM RealView编译工具。它包括如下几部分: ARM C/C++编译器(armcc)MicrolibARM汇...
  • mezely
  • mezely
  • 2015年10月10日 22:03
  • 671

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

0x00 用到的书籍 《Android软件安全与逆向分析》第六章 0x01 原生程序的生成过程笔者是在Linux环境下测试的,详细过程见书中说明需要编译的C语言代码#include int mai...
  • u013736724
  • u013736724
  • 2016年11月17日 15:21
  • 1867

Android逆向—ARM汇编(一)

Android逆向—ARM汇编(一) ARM概述 ARM处理器是英国Acorn有限公司设计的低功耗成本的第一款RISC微处理器。全称为Acorn RISC Machine。ARM处理器本身是32位设...
  • refactor__design
  • refactor__design
  • 2016年11月18日 00:08
  • 499

ARM 汇编学习——编写简单的ARM汇编程序

首先,我们先看一个简单的汇编程序: area ff,code,readonly ;声明代码段 code32 ;声明为32位ARM指令 entry ;声明程序入口 start ;b指令...
  • zqixiao_09
  • zqixiao_09
  • 2016年02月23日 18:40
  • 4919

常用ARM指令及汇编【一】

常用ARM指令及汇编包括1、ARM处理器寻址方式2、指令集介绍3、伪指令4、ARM汇编程序设计5、C与汇编混合编程ARM处理器寻址方式1、寄存器寻址:操作数的值在寄存器中,指令中的地址码字段指出的是寄...
  • XiaoMT_Rush
  • XiaoMT_Rush
  • 2010年07月23日 09:23
  • 8334

ARM汇编必知必会

ARM指令集: ADC 带进位的32位数加法 ADD 32位数相加 AND 32位数的逻辑与 B 在32M空间内的相对跳转指令 BIC 32位数的逻辑位清零 BKPT 断点指令 BL 带...
  • a1875566250
  • a1875566250
  • 2013年01月15日 20:16
  • 20650

AT91Bootstrap1.16源码中连接脚本文件(elf32-littlearm.lds)分析

该连接文件在AT91Bootstrap1.16\Bootstrap-v1.16目录下 elf32-littlearm.lds 连接脚本文件主要用于规定如何把输入文件内的section放入输...
  • feihongwang
  • feihongwang
  • 2011年10月10日 19:43
  • 2043

Gnu arm汇编说明 包括链接脚本文件的使用

1.        汇编系统预定义段名:.text: @代码段;.data: @初始化数据段;.bss: @为初始化数据段;注意:源程序中的.bss段应该位于.data之前;2.        定义入...
  • zhangdi19821125
  • zhangdi19821125
  • 2010年06月09日 16:10
  • 1056

arm系统启动后运行 helloworld ("hello world" 被封装为ramdisk)

---------------------------------------- arm系统启动后运行 helloworld -------------------------------------...
  • hejinjing_tom_com
  • hejinjing_tom_com
  • 2015年07月07日 16:51
  • 953
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:GNU ARM汇编--(二)汇编编译链接与运行
举报原因:
原因补充:

(最多只允许输入30个字)