您的位置:首页 > 编程语言

c和汇编混合编程

2017-12-14 22:34 134 查看
一、栈初始化

栈是一种具有后进先出性质的数据组织方式,也就是说后存放的先取出,先存放的

后取出。栈底是第一个进栈的数据所处的位置,栈顶是最后一个进栈的数据所处的

位置

根据SP指针指向的位置,栈可以分为满栈和空栈。
1. 满栈:当堆栈指针SP总是指向最后压入堆栈的数据

2. 空栈:当堆栈指针SP总是指向下一个将要放入数据的空位置

ARM采用满栈

根据SP指针移动的方向,栈可以分为升栈和降栈。
1. 升栈:随着数据的入栈,
SP指针从低地址->高地址移动

2. 降栈:随着数据的入栈,
SP指针从高地址->低地址移动

ARM采用降栈!

栈帧(stack frame)
就是一个函数所使用的那部分栈,所有函数的栈帧串起来就组成了一个完整的栈。

栈帧的两个边界分别由fp(r11)和sp(r13)来限定



初始化堆栈 

init_stack:
ldr sp, =0x34000000
mov pc ,lr

二、Bss段初始化

clean_bss:
ldr r0, =bss_start //从.lds文件获取
ldr r1, =bss_end
cmp r0, r1
moveq pc, lr

clean_loop:
mov r2, #0
str r2, [r0], #4
cmp r0, r1
bne clean_loop
mov pc, lr

初始化的全局变量: 数据段

局部变量  :栈

malloc   :堆

未初始化的全局变量:  BSS段

#include <stdio.h>

int year;

int test=123;

int main()

{

    int temp=4567;

    year=2019;

    return year;

}

arm-linux-gcc bss.c -o bss

arm-linux-readelf -a bss >dump

cat dump

.......

    76: 0001101c     0 NOTYPE  WEAK   DEFAULT   23 data_start

    77: 000082d8     0 FUNC    GLOBAL DEFAULT  UND abort@@GLIBC_2.4

    78: 000083f4     4 FUNC    GLOBAL DEFAULT   13 __libc_csu_fini

    79: 000082fc     0 FUNC    GLOBAL DEFAULT   13 _start

    80: 000082e4     0 FUNC    GLOBAL DEFAULT  UND __libc_start_main@@GLIBC_

    81: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __gmon_start__

    82: 00000000     0 NOTYPE  WEAK   DEFAULT  UND _Jv_RegisterClasses

    83: 00008468     0 FUNC    GLOBAL DEFAULT   14 _fini

    84: 00008474     4 OBJECT  GLOBAL DEFAULT   15 _IO_stdin_used

    85: 0001101c     0 NOTYPE  GLOBAL DEFAULT   23 __data_start

    86: 00011028     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start__

    87: 00008480     0 NOTYPE  GLOBAL DEFAULT  ABS __exidx_end

    88: 00011020     0 OBJECT  GLOBAL HIDDEN   23 __dso_handle

    89: 0001102c     4 OBJECT  GLOBAL DEFAULT   24 year

    90: 00011030     0 NOTYPE  GLOBAL DEFAULT  ABS __end__

    91: 000083f8   112 FUNC    GLOBAL DEFAULT   13 __libc_csu_init
    92: 00011030     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_end__

    93: 00011028     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start


    94: 00011030     0 NOTYPE  GLOBAL DEFAULT  ABS _bss_end__

    95: 00011024     4 OBJECT  GLOBAL DEFAULT   23 test

    96: 00011030     0 NOTYPE  GLOBAL DEFAULT  ABS _end

    97: 00011028     0 NOTYPE  GLOBAL DEFAULT  ABS _edata

    98: 00008478     0 NOTYPE  GLOBAL DEFAULT  ABS __exidx_start

    99: 000083b0    68 FUNC    GLOBAL DEFAULT   13 main

   100: 000082b4     0 FUNC    GLOBAL DEFAULT   11 _init

三、汇编调用C函数

main.c

#define GPBCON (volatile unsigned long*)0x56000010
#define GPBDAT (volatile unsigned long*)0x56000014

int gboot_main()
{
*(GPBCON) = 0x15400;
*(GPBDAT) = 0x61F;  //根据汇编得来

return 0;
}

/*light_led:
ldr r0, =GPBCON
ldr r1, =0x15400
str r1, [r0]

ldr r0, =GPBDAT
ldr r1, = 0x61F
str r1, [r0]
mov pc, lr
*/


start.S
.text
.global _start
_start:
b reset
ldr pc, _undifined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq

_undifined_instruction: .word undifined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word reset

undifined_instruction:
nop

software_interrupt:
nop

prefetch_abort:
nop

data_abort:
nop

not_used:
nop

irq:
nop

fiq:
nop

reset:
bl set_svc
bl disable_watchdog
bl disable_interrupt
bl disable_mmu
bl init_clock
bl init_sdram
bl copy_to_ram
bl init_stack
bl clean_bss
ldr pc, =gboot_main //调用C的函数
@	bl light_led  //注释掉原来用到的会变函数

set_svc:
mrs r0, cpsr
bic r0, r0,#0x1f
orr r0, r0,#0xd3
msr cpsr, r0
mov pc, lr

#define pWTCON 0x53000000
disable_watchdog:
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0]
mov pc, lr

disable_interrupt:
mvn r1, #0x0
ldr r0, =0x4a000008
str r1, [r0]
mov pc, lr

disable_mmu:
mcr p15,0,r0,c7,c7,0
mrc p15,0,r0,c1,c0,0
bic r0, r0, #0x00000007
mcr p15,0,r0,c1,c0,0
mov pc, lr

#define CLKDIVN 0x4c000014
#define MPLLCON 0x4c000008
#define MPLL_405MHZ ((127<<12)|(2<<4)|(1<<0))

init_clock:
ldr r0, =CLKDIVN
mov r1, #0x5
str r1, [r0]

mcr p15,0,r0,c1,c0,0
orr r0,r0,#0xc0000000
mcr p15,0,r0,c1,c0,0

ldr r0, =MPLLCON
ldr r1, =MPLL_405MHZ
str r1, [r0]
mov pc, lr

#define mem_contrl 0x48000000
init_sdram:
ldr r0, =mem_contrl
add r3, r0, #4*13
adrl r1, mem_data

0:
ldr r2, [r1], #4
str r2, [r0], #4
cmp r0, r3
bne 0b
mov pc, lr

copy_to_ram:
ldr r0, =0x0
ldr r1, =0x30008000
add r3, r0, #1024*4

copy_loop:
ldr r2, [r0], #4
str r2, [r1], #4
cmp r0, r3
bne copy_loop
mov pc, lr

init_stack:
ldr sp, =0x34000000
mov pc ,lr

clean_bss:
ldr r0, =bss_start
ldr r1, =bss_end
cmp r0, r1
moveq pc, lr

clean_loop:
mov r2, #0
str r2, [r0], #4
cmp r0, r1
bne clean_loop
mov pc, lr

mem_data:
.long 0x22000000
.long 0x00000700
.long 0x00000700
.long 0x00000700
.long 0x00000700
.long 0x00000700
.long 0x00000700
.long 0x00018001
.long 0x00018001
.long 0x008c04f5
.long 0x000000b1
.long 0x00000030
.long 0x00000030

#define GPBCON 0x56000010
#define GPBDAT 0x56000014
light_led:
ldr r0, =GPBCON
mov r1, #0x400
str r1, [r0]

ldr r0, =GPBDAT
mov r1, #0x0
str r1, [r0]
mov pc, lr


四、C调用汇编函数


main.c

#define GPBCON (volatile unsigned long*)0x56000010
#define GPBDAT (volatile unsigned long*)0x56000014

int gboot_main()
{
// *(GPBCON) = 0x15400;
// *(GPBDAT) = 0x61F;
light_led();
return 0;
}

/*light_led:
ldr r0, =GPBCON
ldr r1, =0x15400
str r1, [r0]

ldr r0, =GPBDAT
ldr r1, = 0x61F
str r1, [r0]
mov pc, lr
*/


start.S

.text
.global _start
_start:
b reset
ldr pc, _undifined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq

_undifined_instruction: .word undifined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word reset

undifined_instruction:
nop

software_interrupt:
nop

prefetch_abort:
nop

data_abort:
nop

not_used:
nop

irq:
nop

fiq:
nop

reset:
bl set_svc
bl disable_watchdog
bl disable_interrupt
bl disable_mmu
bl init_clock
bl init_sdram
bl copy_to_ram
bl init_stack
bl clean_bss
ldr pc, =gboot_main
@	bl light_led

set_svc:
mrs r0, cpsr
bic r0, r0,#0x1f
orr r0, r0,#0xd3
msr cpsr, r0
mov pc, lr

#define pWTCON 0x53000000
disable_watchdog:
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0]
mov pc, lr

disable_interrupt:
mvn r1, #0x0
ldr r0, =0x4a000008
str r1, [r0]
mov pc, lr

disable_mmu:
mcr p15,0,r0,c7,c7,0
mrc p15,0,r0,c1,c0,0
bic r0, r0, #0x00000007
mcr p15,0,r0,c1,c0,0
mov pc, lr

#define CLKDIVN 0x4c000014
#define MPLLCON 0x4c000008
#define MPLL_405MHZ ((127<<12)|(2<<4)|(1<<0))

init_clock:
ldr r0, =CLKDIVN
mov r1, #0x5
str r1, [r0]

mcr p15,0,r0,c1,c0,0
orr r0,r0,#0xc0000000
mcr p15,0,r0,c1,c0,0

ldr r0, =MPLLCON
ldr r1, =MPLL_405MHZ
str r1, [r0]
mov pc, lr

#define mem_contrl 0x48000000
init_sdram:
ldr r0, =mem_contrl
add r3, r0, #4*13
adrl r1, mem_data

0:
ldr r2, [r1], #4
str r2, [r0], #4
cmp r0, r3
bne 0b
mov pc, lr

copy_to_ram:
ldr r0, =0x0
ldr r1, =0x30008000
add r3, r0, #1024*4

copy_loop:
ldr r2, [r0], #4
str r2, [r1], #4
cmp r0, r3
bne copy_loop
mov pc, lr

init_stack:
ldr sp, =0x34000000
mov pc ,lr

clean_bss:
ldr r0, =bss_start
ldr r1, =bss_end
cmp r0, r1
moveq pc, lr

clean_loop:
mov r2, #0
str r2, [r0], #4
cmp r0, r1
bne clean_loop
mov pc, lr

mem_data:
.long 0x22000000
.long 0x00000700
.long 0x00000700
.long 0x00000700
.long 0x00000700
.long 0x00000700
.long 0x00000700
.long 0x00018001
.long 0x00018001
.long 0x008c04f5
.long 0x000000b1
.long 0x00000030
.long 0x00000030

#define GPBCON 0x56000010
#define GPBDAT 0x56000014
.global light_led
light_led:
ldr r0, =GPBCON
mov r1, #0x400
str r1, [r0]

ldr r0, =GPBDAT
mov r1, #0x0
str r1, [r0]
mov pc, lr


五、C内嵌汇编

C内嵌汇编-格式 

__asm__(
汇编语句部分
:输出部分
:输入部分
:破坏描述部分
);

C内嵌汇编以关键字”__asm__”或”asm”开始,下辖四个部分,各部分之间使用":"分开,第一部分是必须写的,后面三部分是可以省略,但是分号:不能省略!

1.汇编语句部分:汇编语句的集合,可以包含多条汇编语句,每条语句之间需要使用换行符“\n”隔开或使用分号“ ; ”隔开。
2.输出部分:在汇编中被修改的C变量列表
3.输入部分:作为参数输入到汇编中的变量列表
4.破坏描述部分:执行汇编指令会破坏的寄存器描述

void write_p15_c1 (unsigned long value)

{

__asm__(
“mcr p15, 0,
%0, c1, c0, 0\n”
:
: “r” (value)
@编译器选择一个R*寄存器
: "memory");

}

unsigned long read_p15_c1 (void)

{

unsigned long value;
__asm__(
“mrc p15, 0,
%0, c1, c0, 0\n”
: “=r” (value)@
’=‘表示只写操作数,用于输出部
:

: "memory");

return value;

}

unsigned long old;

unsigned long temp;

__asm__ volatile(

"mrs %0, cpsr \n"
"orr %1, %0, #128 \n“

"msr cpsr_c, %1\n"

: "=r“ (old), "=r“ (temp)



:"memory") ;

使用volatile来告诉编译器,不要对接下来的这部分代码进行优化 。


main.c
#define GPBCON 0x56000010
#define GPBDAT 0x56000014

int gboot_main()
{
// *(GPBCON) = 0x15400;
// *(GPBDAT) = 0x61F;
//light_led();
__asm__(
"ldr r1, =0x400\n"
"str r1, [%0]\n"
"ldr r1, = 0x0\n"
"str r1, [%1]\n"
:
:"r"(GPBCON),"r"(GPBDAT)
:"r1"
);
return 0;
}

/*#define GPBCON 0x56000010
#define GPBDAT 0x56000014
light_led:
ldr r0, =GPBCON
ldr r1, =0x15400
str r1, [r0]

ldr r0, =GPBDAT
ldr r1, = 0x61F
str r1, [r0]
mov pc, lr
*/


start.S
.text
.global _start
_start:
b reset
ldr pc, _undifined_instruction
ldr pc, _software_interrupt
ldr pc, _prefetch_abort
ldr pc, _data_abort
ldr pc, _not_used
ldr pc, _irq
ldr pc, _fiq

_undifined_instruction: .word undifined_instruction
_software_interrupt: .word software_interrupt
_prefetch_abort: .word prefetch_abort
_data_abort: .word data_abort
_not_used: .word not_used
_irq: .word irq
_fiq: .word reset

undifined_instruction:
nop

software_interrupt:
nop

prefetch_abort:
nop

data_abort:
nop

not_used:
nop

irq:
nop

fiq:
nop

reset:
bl set_svc
bl disable_watchdog
bl disable_interrupt
bl disable_mmu
bl init_clock
bl init_sdram
bl copy_to_ram
bl init_stack
bl clean_bss
ldr pc, =gboot_main  //调用C的函数

set_svc:
mrs r0, cpsr
bic r0, r0,#0x1f
orr r0, r0,#0xd3
msr cpsr, r0
mov pc, lr

#define pWTCON 0x53000000
disable_watchdog:
ldr r0, =pWTCON
mov r1, #0x0
str r1, [r0]
mov pc, lr

disable_interrupt:
mvn r1, #0x0
ldr r0, =0x4a000008
str r1, [r0]
mov pc, lr

disable_mmu:
mcr p15,0,r0,c7,c7,0
mrc p15,0,r0,c1,c0,0
bic r0, r0, #0x00000007
mcr p15,0,r0,c1,c0,0
mov pc, lr

#define CLKDIVN 0x4c000014
#define MPLLCON 0x4c000008
#define MPLL_405MHZ ((127<<12)|(2<<4)|(1<<0))

init_clock:
ldr r0, =CLKDIVN
mov r1, #0x5
str r1, [r0]

mcr p15,0,r0,c1,c0,0
orr r0,r0,#0xc0000000
mcr p15,0,r0,c1,c0,0

ldr r0, =MPLLCON
ldr r1, =MPLL_405MHZ
str r1, [r0]
mov pc, lr

#define mem_contrl 0x48000000
init_sdram:
ldr r0, =mem_contrl
add r3, r0, #4*13
adrl r1, mem_data

0:
ldr r2, [r1], #4
str r2, [r0], #4
cmp r0, r3
bne 0b
mov pc, lr

copy_to_ram:
ldr r0, =0x0
ldr r1, =0x30008000
add r3, r0, #1024*4

copy_loop:
ldr r2, [r0], #4
str r2, [r1], #4
cmp r0, r3
bne copy_loop
mov pc, lr

init_stack:
ldr sp, =0x34000000
mov pc ,lr

clean_bss:
ldr r0, =bss_start
ldr r1, =bss_end
cmp r0, r1
moveq pc, lr

clean_loop:
mov r2, #0
str r2, [r0], #4
cmp r0, r1
bne clean_loop
mov pc, lr

mem_data:
.long 0x22000000
.long 0x00000700
.long 0x00000700
.long 0x00000700
.long 0x00000700
.long 0x00000700
.long 0x00000700
.long 0x00018001
.long 0x00018001
.long 0x008c04f5
.long 0x000000b1
.long 0x00000030
.long 0x00000030
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: