C语言调用汇编和汇编调用C语言

1.C语言调用汇编

程序的入口是main,在main里调用汇编的函数。

在C语言中,要extern 一个函数声明即可,然后这个函数在汇编里面实现。

在汇编里面,用EXPORT 把C语言定义的函数名引进来,再开始编写函数名开始的段

#include<stdio.h>
extern int sum(int a,int b,int c,int d,int e,int f);
int main(){
    int result = sum(1,2,3,4,5,6);  
    return 0; 
}
汇编代码可新建一个sum.asm文件,在工程中添加这个文件即可。        
        AREA    EXAMPLE,CODE,READONLY
        EXPORT    sum
        ENTRY
        
sum
        ADD R0,R0,R1
        ADD R2,R2,R3
        ADD R0,R0,R2
        
        LDR    R4,[SP]
        LDR R5,[SP,#4]
        
        ADD R4,R4,R5
        ADD R0,R4,R0
        
        BX LR
        
        END
函数传参:

4个以内的参数,直接存放在R0~R3 这4个寄存器里面。

4个以后的参数放在堆栈里。

如果函数有返回值,那么返回值放在R0里。

Debug看看编译器是怎么处理的,我们就怎样把参数取出来。

还是比较易懂

首先是

R0 =6   R1=5   R2=4   R3=3

然后把R1的值放在堆栈里,R13=5,然后R1=2

然后吧R0的值放在堆栈的下一个位置,R13+4=6,然后R0=1.

之后就是:

R0=1,R1=2,R2=3,R3=4

堆栈里面:

所以取参数的时候就是:

LDR    R4,[SP];R4=5
LDR R5,[SP,#4];R5=6

把相加的结果放在R0,然后BX LR返回

可以看到:

可以验证的确R0是存放返回值的。


例子:

;C语言中extern void macRM68090_WR_CMD(int cmd);  R0 为cmd
    AREA    EXAMPLE,CODE,READONLY
    EXPORT    macRM68090_WR_CMD
    ENTRY
        
macRM68090_WR_CMD
	;macRM68090_RS_CLR;macRM68090_CS_CLR 
	LDR R1, =0x30 
	ldr r4, =0x40010C14 
	STR R1, [r4]            ; GPIOB->BRR = 0x10; GPIOB->BRR = 0x20;  
	          	
	;macRM68090_8BIT_DATAOUT(cmd&0xFF00); 
	AND R1, R0, #0xFF00
	LDR R3, =0x40010C0C
	AND R3, R3, #0X00FF
	ORR R2, R1, R3
	ldr r4, =0x40010C0C 
	STR R2, [r4]
	
	;macRM68090_WR_CLR;macRM68090_WR_SET 
	LDR R1, =0x08
	ldr r4, =0x40010C14 
	STR R1, [r4]             ;GPIOB->BRR = 0x08;
    ldr r4, =0x40010C10 	
	STR R1, [r4]            ;GPIOB->BSRR = 0x08;  
	
	;macRM68090_8BIT_DATAOUT(((cmd<<8)&0xFF00));
	MOV R2, R0, LSL#8
	AND R2, R2, #0xFF00
	LDR R3, =0x40010C0C
	AND R3, R3, #0x00FF
	ORR R2, R0, R3
    ldr r4, =0x40010C0C 
	STR R2, [r4] 
	
	;macRM68090_WR_CLR ; 
	ldr r4, =0x40010C14 
	STR R1, [r4]  ; GPIOB->BRR = 0x08;   
	
	;macRM68090_WR_SET ;macRM68090_CS_SET
	LDR R1, =0x28  
	ldr r4, =0x40010C10 
	STR R1, [r4]  ; GPIOB->BSRR = 0x08; GPIOB->BSRR = 0x20; 
	
    BX LR
    NOP	
	END

;C语言中extern void macRM68090_WR_DATA(int data);  R0 为data
    AREA    EXAMPLE,CODE,READONLY
    EXPORT    macRM68090_WR_DATA
    ENTRY
	
macRM68090_WR_DATA
	;macRM68090_RS_SET
	LDR R1, =0x10  
	ldr r4, =0x40010C10 
	STR R1, [r4]   ; GPIOB->BSRR = 0x10;
	
	;macRM68090_CS_CLR 
	LDR R1, =0x20 
	ldr r4, =0x40010C14 
	STR R1, [r4]             ;  GPIOB->BRR = 0x20; 
	
	;macRM68090_8BIT_DATAOUT(data&0xFF00);          	
	AND R1, R0, #0xFF00
	LDR R3, =0x40010C0C
	AND R3, R3, #0X00FF
	ORR R2, R1, R3
	ldr r4, =0x40010C0C 
	STR R2, [R4]
	
	;macRM68090_WR_CLR;macRM68090_WR_SET 
	LDR R1, =0x08
	ldr r4, =0x40010C14 
	STR R1, [R4]             ;GPIOB->BRR = 0x08; 
	ldr r4, =0x40010C10 
	STR R1, [R4]           ;GPIOB->BSRR = 0x08; 
	
	;macRM68090_8BIT_DATAOUT(((data<<8) &0xFF00));
	MOV R2, R0, LSL#8
	AND R2, R2, #0xFF00
	LDR R3, =0x40010C0C
	AND R3, R3, #0x00FF
	ORR R2, R0, R3
	ldr r4, =0x40010C0C 
	STR R2, [R4]
	
	;macRM68090_WR_CLR ;  
	ldr r4, =0x40010C14 
	STR R1, [r4]  ; GPIOB->BRR = 0x08;  
	
	;macRM68090_WR_SET ;macRM68090_CS_SET
	LDR R1, =0x28 
    ldr r4, =0x40010C10 	
	STR R1, [R4]  ; GPIOB->BSRR = 0x08; GPIOB->BSRR = 0x20; 
	
    BX LR
    NOP	
	END

Keil: warning: A1581W: Added 2 bytes of padding at address

KEIL MDK编译警告:

 

warning: A1581W: Added 2 bytes of padding at address xxx

image

原因:

在Keil 里写汇编代码时如果代码尺寸不对齐,编译器自动补补警告。

 

处理办法:

 

加NOP指令,或修改对齐方式

 

 image


  • 13
    点赞
  • 67
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值