Mixed C and Assembly Language Programming for STM32 under Keil5

Keywords: C stm32

stay Creating STM32 Assembly Language Project Based on Keil5 On this basis, continue to learn the mixed programming of C and assembly language for STM32 under Keil5.

  • Contents of this article:
    1. Refer to the attachments to complete the C language call assembly function;
    2. Modifying the code requires changing the type of Init_1 function in the original assembly language to int Init_1(init). This function is modified to pass in an integer x and returns the integer x+100 after the function runs. It is implemented programmatically and simulates trace debugging.
    3. If you need to call a function written in C in an assembly function, how do you modify the assembly code?

1.C language calls assembly functions

1.Project Creation

2.Write code

  • func.s
	AREA My_Function,CODE,READONLY  ;This line must have, except My_Function They are templates, except for their own names.
	EXPORT Init_1  ;And.c Defined in the file Init_1 Functional Relevance
		;Declarations and use of variables in high-level languages are actually the use of board registers, so we only need to use registers directly.
Init_1
	MOV R1,#0;The register set to R1 is i
	MOV R2,#0;Set the register for R2 to j
	
LOOP  ;On the leftmost side is the segment name, which is used to execute jump programs
	CMP R1,#10;Compare R1 and 10 sizes
	BHS LOOP_END ;If R1 Greater than or equal to 10, jump to LOOP_END Segment; otherwise ignore the statement and execute the following statement directly.
	ADD R2,#1  ;j++
	ADD R1,#1  ;i++
	B LOOP     ;After a loop is executed, unconditionally re-enter the loop judgment, jumping to both LOOP paragraph
	
LOOP_END   ;On the leftmost side is the segment name, which is used to execute jump programs
	NOP
	
	END    ;Must be blank before writing END,Otherwise, it will be considered a segment name, indicating the end of the program.

  • main.c
#include<stdio.h>
extern void Init_1(void);
int main()
{
	Init_1();
	return 0;
}

3.Configuration environment and code run

(1) Emulator setup and compilation

  • Open the magic wand, select Use Simulator under Debug, change the contents of Dialog DLL at the bottom left to DARMSTM.DLL, and change the contents of Parameter to -pSTM32F103C8
  • Click Rebuild to compile
    main.c

    func.s

(2) Program debugging

  • Ctrl+F5, start debugging
  • Set Breakpoint
  • Click Step for step debugging


    By observing the changes of the register values of R1 and R2, we find that they increase gradually from 0 to 10.
    Explains that C successfully invoked the assembler!

2.Modify function functions

Change the type of Init_1 function in the original assembly language to int Init_1(init), modify the function to pass in an integer x, and return the integer x+100 after the function runs

(1) Modify the code

main.c

#include<stdio.h>

extern int Init_1(int x);

int main(){
	
	int xx = Init_1(10);
	printf("%d", xx);
	
	return 0;
}

func.s

	AREA	MY_Function,CODE,READONLY
	EXPORT 	Init_1  ; And c Defined in the file Init_1 Functional Relevance


; Declarations and usage variables in high-level languages are actually the use of board registers, so we just need to use registers directly

Init_1
	ADD R0,#100;The value to be passed in+100
	MOV PC,LR		; Return R0
	
	
LOOP	; Written on the leftmost side is the segment name used to execute the jump program
	CMP R1,#10;Compare R1 and 10 sizes
	BHS LOOP_END  	  ; If R1 Greater than or equal to 10, jump to LOOP_END Segment, otherwise ignore the statement and execute the following statement directly
	ADD R2,#1	  ; j++
	ADD R1,#1     ; i++
	B LOOP		  ; loop
	
LOOP_END
	NOP	
	
	
	END  ; Must be blank before writing END,Otherwise, it will be considered a segment name, indicating the end of the program

In Keil, parameter value transfers of subfunctions are stored in R0, R1, R2, R3 in sequence, and more than four parameter value transfers are placed in the stack frame, so the 10 passed in by Init_1(10) is placed in R0 and returned by MOV PC and LR to 110.

(2) Setting breakpoints


(3) Compile and debug

Click Run to Cursor Line



When the main function calls the Init_1 function, giving parameter 10, when the function is executed, the 16-digit number of 10+100 is 6E, and the value of register R0 is 6E. The call is successful!

3.Assembly function calls C language function

Call C language function XXX in assembly, then add IMPORT XXX, note that Keil tool does not allow assembly statement top case writing, otherwise error will occur

(1) New func_.s, main_.c

(2) Writing code

  • func_.s
	AREA	MY_Function,CODE,READONLY
	EXPORT 	Init_1  ; And c Defined in the file Init_1 Functional Relevance
	IMPORT  get5    ; statement get5 For external reference


; Declarations and usage variables in high-level languages are actually the use of board registers, so we just need to use registers directly

Init_1

	MOV R1,#0;Set R1 register to i
	MOV R2,#0;Set R2 register to j
	
LOOP	; Written on the leftmost side is the segment name used to execute the jump program
	CMP R1,#10;Compare R1 and 10 sizes
	BHS LOOP_END  	  ; If R1 Greater than or equal to 10, jump to LOOP_END Segment, otherwise ignore the statement and execute the following statement directly
	ADD R2,#1	  ; j++
	ADD R1,#1     ; i++
	BL get5  	  ; call get5,Return value passed in R0
	B LOOP		  ; loop
	
LOOP_END
	NOP	
	
	
	END  ; Must be blank before writing END,Otherwise, it will be considered a segment name, indicating the end of the program
  • main_.c
include<stdio.h>

extern void	Init_1(void);

int get5(void);

int main(){
	
	printf("Begin...\n");
	Init_1();

	
	return 0;
}

int get5(){
	return 5;
}

(3) Compile and debug

  • Click Rebuild to compile
  • Set Breakpoint


    After get5 is executed, the register value R0 changes to 5 and the call succeeds!

4.summary

This paper explains the process of C and assembly language mixed programming through specific examples, which gives us a deeper understanding of C calling assembly language and the principle of C calling assembly language. It also gives us a certain understanding of how to transfer the parameters of calling function and how to use ARM register. C calling assembly program uses EXTERN declaration in C program and EXPORT to transfer C functions and sinks in assembly file.Programming functions are linked; the assembler calls C language files with IMPORT in the assembler file.
The article is for reference only. If there are any mistakes, you are welcome to discuss them together~

5.Reference

https://blog.csdn.net/qq_45659777/article/details/120651310
https://blog.csdn.net/longintchar/article/details/79511747

Posted by ahmed17 on Wed, 13 Oct 2021 10:54:36 -0700