__asm
{
instruction [; instruction]
…
[instruction]
}
asm(“instruction [; instruction]”);
#include
void my_strcpy(const char *src, char *dest)
{
char ch;
__asm
{
loop:
ldrb ch, [src], #1
strb ch, [dest], #1
cmp ch, #0
bne loop
}
}
int main()
{
char *a = "forget it and move on!";
char b[64];
my_strcpy(a, b);
printf("original: %s", a);
printf("copyed: %s", b);
return 0;
}
Here, the value transfer between C and assembly is implemented using C pointers. Since pointers correspond to addresses, they can also be accessed in assembly.
#include
int gVar_1 = 12;
extern asmDouble(void);
int main()
{
printf("original value of gVar_1 is: %d", gVar_1);
asmDouble();
printf(" modified value of gVar_1 is: %d", gVar_1);
return 0;
}
;called by main(in C),to double an integer, a global var defined in C is used.
AREA asmfile, CODE, READONLY
EXPORT asmDouble
IMPORT gVar_1
asmDouble
ldr r0,=gVar_1
ldr r1, [r0]
move r2, #2
mul r3, r1, r2
str r3, [r0]
mov pc, lr
END
#include
extern void asm_strcpy(const char *src, char *dest);
int main()
{
const char *s = "seasons in the sun";
char d[32];
asm_strcpy(s, d);
printf("source: %s", s);
printf(" destination: %s",d);
return 0;
}
;asm function implementation
AREA asmfile, CODE, READONLY
EXPORT asm_strcpy
asm_strcpy
loop
ldrb r4, [r0], #1 ;address increment after read
cmp r4, #0
frog over
strb r4, [r1], #1
b loop
over
mov pc, lr
END
Here, the parameter passing between C and assembly is carried out according to the provisions of ATPCS (ARM Thumb Procedure Call Standard). Simply put, if a function has no more than four parameters, they are passed using R0-R3. If there are more than four, the stack is used, and the return value of the function is returned through R0.
;the details of parameters transfer comes from ATPCS
;if there are more than 4 args, stack will be used
EXPORT asmfile
AREA asmfile, CODE, READONLY
IMPORT cFun
ENTRY
mov r0, #11
mov r1, #22
rice r2, #33
BL cFun
END
int cFun(int a, int b, int c)
{
return a + b + c;
}
When calling a C function in assembly, the parameter passing is also implemented through ATPCS. It should be pointed out that when the number of function parameters is greater than 4, the stack must be used. For details, see the ATPCS specification.
The above examples demonstrate some common C and assembly mixed programming methods and basic ideas in embedded development. In fact, the core issue is how to pass values between C and assembly. The rest is to handle them in their own way. The above is just a starting point. For more detailed and complex usage methods, you need to combine actual applications and refer to relevant materials.
illustrate
The above code is compiled in the ADS 1.2 project and passed the software simulation in the corresponding AXD.
When programming in C and assembly, there are interface issues between variables and functions in C and assembly.
Variables defined in a C program are put into the .bss area after being compiled into an .asm file, and the variable names are preceded by an underscore. Functions defined in a C program are also preceded by an underscore after being compiled. For example:
extern int num becomes .bss _num, 1
extern float nums[5] becomes .bss _nums, 5
extern void func ( ) becomes _func, The mutual calls between assembly and C can be divided into the following situations:
(1) Accessing variables and functions in a C program in an assembly program.
In
an assembly program, you can use _XX to access variable XX in C. When accessing an array, you can use _XX+offset to access it, such as _XX+3 to access XX[3] in the array. When calling a C function in an assembly program, if no parameters are passed, you can directly use _funcname. If there are parameters to be passed, the leftmost parameter in the function is given by register A, and the other parameters are given in order from the stack. The return value is returned to register A or the address given by register A. Also note that in order for assembly language to access variables and functions defined in C language, they must be declared as external variables, that is, with the extern prefix.
(2) Accessing variables in the assembly program in the C program
If you need to access variables in the assembly program in the C program, the variable name in the assembly program must start with an underscore and use global to make it a global variable.
If you need to call a procedure in the assembly program in the C program, the procedure name must start with an underscore, and the procedure must be correctly written according to the mode used when the C program is compiled, whether it is the stack-based model or the register argument model, so that it can correctly obtain the calling parameters.
(3) Online assembly Directly insert asm(" *** ")
into the C program , embed assembly statements. It should be noted that this usage should be used with caution. Online assembly provides the ability to directly read and write hardware, such as reading and writing interrupt control enable registers, but the compiler does not check and analyze online assembly language. Inserting online assembly language to change the assembly environment or possibly change the value of C variables may cause serious errors.
2. Changes in addressing methods in assembly and C interfaces:
It should be noted that in C language, the creation and access of local variables are implemented through the stack, and its addressing is implemented through the stack register SP. In assembly language, in order to make the program code more concise, in the direct addressing mode, the lower 7 bits of the address are directly included in the instruction. The specific location that these lower 7 bits can address can be determined by the DP register or the SP register. The specific implementation can be achieved by setting the CPL bit of the ST1 register. CPL=0, DP addressing, CPL=1, SP addressing. When DP addressing is used, DP provides the high 9-bit address, which together with the low 7 bits form a 16-bit address; when SP addressing is used, the 16-bit address is obtained by directly adding SP (16 bits) and the low 7 bits.
Since in the C language environment, the addressing of local variables must be implemented through the SP register, in mixed programming, in order to prevent the assembly language from affecting the stack register SP, the usual way is to use DP addressing in the assembly environment, so that the two do not interfere with each other. In programming, just pay attention to the correct setting of the CPL bit.
Previous article:Porting MySQL to Embedded ARM Platform
Next article:ARM Assembly Example - Button LED (Loop)
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- The 77GHz millimeter wave chip made in China is here, breaking the world record
- Installation of Armbian system on MaixSense R329 development board
- Transfer of a number of idle personal 100M digital oscilloscope signal generators
- 【ATmega4809 Curiosity Nano Review】Timer
- CPU reads and writes memory
- TI C2000 LaunchPad uses official routines to compile and debug
- How to configure TMS570 HAL CODEGEN
- ISA bus interface
- MicroPython now runs on the LEGO MINDSTORMS Inventor Hub
- What is the file with the suffix jed? What is its function?