将ARM ADS下的汇编码移植到GCC for ARM编译器时,有如下规则:
1, 注释行以"@"或"/* ... */"代替";"
2, GET或INCLUDE => .INCLUDE
如:get option.a => .include "option.a"
3, EQU => .equ
TCLK2 EQU PB25 => .equ TCLK2, PB25
SETA ==> .equ
SETL ==> .equ
BUSWIDTH SETA 16 => .equ BUSWIDTH, 16
4, EXPORT => .global
IMPORT => .extern
GBLL => .global
GBLA => .global
5, DCD => .long
6, IF :DEF: => .IFDEF
ELSE => .ELSE
ENDIF => .ENDIF
:OR: => |
:SHL: => <<
编译控制中:
“[” “|” “]”伪操作可以使用GCC的条件编译控制符代替
如
[ 可以使用.ifdef或.ifeq等代替;
| 使用.else或.elseif
] 用.endif
NOTE:
TRUE,FALSE,CONFIG等都需要自己定义。
7, END =>.end
NOTE:在被include的头文件中,如"option.a"中,不再需要.end,否则会导致主汇编程序结束。
8, 符号定义加":"号
Entry => Entry:
AREA Word, CODE, READONLY ==> .text
AREA Block, DATA, READWRITE ==> .data
CODE32 ==> .arm
CODE16 ==> .thumb
9, LTORG ==> .ltorg
10, % --> .fill
11, 操作数及运算符号替换
ldr pc, [pc, #&18] 替换成 ldr pc, [pc, #+0x18]
“&”以“+0x”号替换
12, MACRO ==> .macro
MEND ==> .endm
NOTE: 在带有宏参数的时候,在使用宏参数时,须在前面加入'\'
eg:
@============================================
.macro HANDLER HandlerLabel,HandleLabel
\HandlerLabel:
sub sp,sp,#4 @decrement sp(to store jump address)
stmfd sp!,{r0} @PUSH the work register to stack(lr does't push because it return to original address)
ldr r0,=\HandleLabel @load the address of HandleXXX to r0
ldr r0,[r0] @load the contents(service routine start address) of HandleXXX
str r0,[sp,#4] @store the contents(ISR) of HandleXXX to stack
ldmfd sp!,{r0,pc} @POP the work register and pc(jump to ISR)
.endm
@=========================================
13 地址转换
^ (_ISR_STARTADDRESS-0x500)
UserStack # 256 /*;c1(c7)ffa00*/
SVCStack # 256 /*;c1(c7)ffb00*/
UndefStack # 256 /*;c1(c7)ffc00*/
AbortStack # 256 /*;c1(c7)ffd00*/
IRQStack # 256 /*;c1(c7)ffe00*/
FIQStack # 0 /*;c1(c7)fff00*/
==>
.data
.equ
UserStack, _ISR_STARTADDRESS-0x500 /* c7ffa00 */
.equ SVCStack,
_ISR_STARTADDRESS-0x500+256 /* c7ffb00 */
.equ
UndefStack,_ISR_STARTADDRESS-0x500+256*2 /* c7ffc00 */
.equ
AbortStack,_ISR_STARTADDRESS-0x500+256*3 /* c7ffd00 */
.equ IRQStack,
_ISR_STARTADDRESS-0x500+256*4 /* c7ffe00 */
.equ FIQStack,
_ISR_STARTADDRESS-0xf00+256*5 /* c7fff00 */
MAP _ISR_STARTADDRESS
SYS_RST_VECTOR # 4
UDF_INS_VECTOR # 4
SWI_SVC_VECTOR # 4
INS_ABT_VECTOR # 4
DAT_ABT_VECTOR # 4
RESERVED_VECTOR # 4
IRQ_SVC_VECTOR # 4
FIQ_SVC_VECTOR # 4
==>
.equ SYS_RST_VECTOR, _ISR_STARTADDRESS
.equ
UDF_INS_VECTOR, _ISR_STARTADDRESS+4
.equ SWI_SVC_VECTOR,
_ISR_STARTADDRESS+4*2
.equ INS_ABT_VECTOR, _ISR_STARTADDRESS+4*3
.equ
DAT_ABT_VECTOR, _ISR_STARTADDRESS+4*4
.equ RESERVED_VECTOR,
_ISR_STARTADDRESS+4*5
.equ IRQ_SVC_VECTOR, _ISR_STARTADDRESS+4*6
.equ
FIQ_SVC_VECTOR, _ISR_STARTADDRESS+4*7
关于伪指令的修改,可下载这个文档google gcc-as-Opcode.chm
14, Image$$RO$$Limit , Image$$RO$$BASE地址的处理,修改下面的链接文件,在连接时使用。修改方法一看即明,来源于
/*******************************************************/
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
. = 0x00000000; /* . refers to the current location
pointer, .text section starts from here */
Image$$RO$$Base = .; /* . Assign $$RO$$B.. to this location */
. = ALIGN(4);
.text : /* .text section */
{
/* define all your object files that contains .text section */
*(.text) /* * refers to all the files included in
linking */
}
. = ALIGN(4); /* Align to 4 bit boundary*/
.rodata : { *(.rodata) }
Image$$RO$$Limit = .; /* refers to the size of the Read-only section
*/
. = 0x30400000; /* Read-Write Section starts from this
location */
Image$$RW$$Base = .; /*. Assign $$RW$$B.. to this location */
. = ALIGN(4);
.data : { *(.data) } /*.data section */
Image$$RW$$Limit = .; /* refers to the size of the Read-Write
section */
. = 0x31400000; /* Zero-Initialised Section starts from
this location */
Image$$ZI$$Base = .; /*. Assign $ZI$$B.. to this location */
. = ALIGN(4);
.bss : { *(.bss) } /* .bss section */
Image$$ZI$$Limit = .; /* refers to the size of the ZI section */
}
/***********************************************************/