Calls between ARM assembler and C

A. Compilation call C

  1. initialize stack

  2. initialize the BSS (the BSS is the C language uninitialized global variable storage, or global variable is initialized to 0) 

  3. Use r0, r1, r2, r3 pass parameters to the function, if more than four transmission parameter stack reference manner

  4. The value is returned r0, r1, a maximum 32-bit data is generally used to meet the requirements r0

Example: compilation of documents start.s

.text @ compilation represents the beginning of the file 

/ initialize the stack **** ***** / 
LDR SP, = 0x40000100 
mov r0, # 0x5
 mov r1, # 0x6 
    
/ initialization bss segment *** *** / 
@ bss segment address the compiler allocates when linked by 
ldr r2, = __ bss_start @ BSS start address of the 
address ldr r3, = __ end bss_end__ @ BSS 
mov r4, # 0x00000000      

clbss_l:   
    TEQ r2, r3 @ r2, r3 are placed by BSS segment start and end address 
    address strne r4, [r2] @ r4 in the data stored in the write r2, teq write the result does not hold, that is, the bss segment write 0 
    ADDNE r2, r2, # 1   @ offset a start address byte, teq not established impoverished under 
    bne clbss_l @ teq not established, expressed finished yet clear bss segment, 
    
    BL _main @ C function name to jump to the implementation of 

.end @ pseudo-ops, it indicates the end of the assembly file

main.c

int aa;
int _main(int a, int b)
{
	int t=0;
	t = a+ b;
	return t;
}

Link files: map.lds

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
/*OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm")*/
OUTPUT_ARCH(arm)
ENTRY(_start)
SECTIONS
{
    . = 0x00000000;
    . = ALIGN(4);
    .text      :
    {
        ./Objects/start.o(.text)
        *(.text)
    }
    . = ALIGN(4);
    .rodata : 
    { *(.rodata) }
    . = ALIGN(4);
    .data : 
    { *(.data) }
    . = ALIGN(4);
    __bss_start = .; 
    .bss :
     { *(.bss) }
    __bss_end__ = .;
}

Test: applying a global variable, int aa; 4-byte account so the BSS segment start and end address difference of 4 bytes, it will be apparent BSS performed in four cycles

 

Two. C to call assembly

When the C language to call assembly as long as the assembly function by .global declared as global functions you can call in the C language

Pass on the parameters:

  C function parameters, to the assembler in registers r0, r1, r2, r3; the assembler will accept the call using the return value registers r0 Assembly Functions

  

Examples: start.s compilation of documents

.text

/****初始化栈*****/
ldr sp, =0x40000100
mov r0, #0x5
mov r1, #0x6

/*   汇编跳转到 C 中   */
/*    初始化bss段    */
@ bss段地址由链接时编译器分配
ldr r2, =__bss_start         @ BSS 起始地址
ldr r3, =__bss_end__         @ BSS 结束地址
mov r4, #0x00000000     

clbss_l:  
    teq r2, r3         @ r2, r3 中存放的是BSS段起始和结束地址
    strne r4, [r2]    @ 把r4 中的数据写入 r2中存放的地址中,teq结果不成立写入,也就是把bss段写0
    addne r2, r2, #1  @ 起始地址开始偏移一个字节,teq不成立的清苦下
    bne clbss_l   @ teq 不成立,表示还没有清除完bss 段,
    
    bl _main   @ 跳转到执行的C 函数名 , lr 中会保存下一条指令的地址, 也就是
    b loop

/*    汇编函数, 在C 中调用   */
.global add_fun @ 声明为全局函数,使外部可调用
add_fun:
    add r2, r1, r0   @ 把 r1和r0中的数据相加 放在r2 中
    mov r0, r2    @ 使用寄存器 r0 存放调用汇编函数时返回的结果
    mov pc, lr    @ lr 寄存器中保存 C 跳转到汇编时的下一条指令地址 , 重新付给 PC 继续执行loop:
    b loop

.end

测试:

 

Guess you like

Origin www.cnblogs.com/electronic/p/11021763.html