Hello,
We want to call C functions with one argument in our assembly program, and we used register d0 to pass the value to the argument, but after we added other software parts, we found it became not working, and by debugging we found d2 is used, and after we changed the register to d2, it worked again. Could anyone tell me what is the correct way?
ld d0,#0
jsr CFunciton
解決済! 解決策の投稿を見る。
Hello Edward,
Thank you very much for the answer. We have function prototype like following and not changed.
void MCUInterface_Init(const McuInitModeType i_mode)
And we have declaration as following in assembly file.
XREF.L MCUInterface_Init
By the way, I searched the folder of Codewarrior installation, and get MCU_S12Z_Assembler.pdf and MCU_S12Z_Compiler.pdf. In the MCU_S12Z_Assembler.pdf, there is "Chapter 12 Mixed C and Assembler Applications", and "12.1 Parameter Passing Scheme
Check the backend chapter in the compiler manual for the details of parameter passing."
But I did not find contents about parameter passing in MCU_S12Z_Compiler.pdf, do you know where can I find such contents? Thanks.
It happened because you changed function prototype, or perhaps you didn't have function prototype at all and compiler thought it should be different for some reason. It could be something like void foo(char), which became void foo(short). D0 and D1 are 8 bits wide registers, D2-D5 - 16 bits wide registers. Look for compiler documentation, just look for *.pdf in your Codewarrior installation. The look in compiler docs for something like calling convention, it should explain when and what registers are used.
Edward
Hello Edward,
Thank you very much for the answer. We have function prototype like following and not changed.
void MCUInterface_Init(const McuInitModeType i_mode)
And we have declaration as following in assembly file.
XREF.L MCUInterface_Init
By the way, I searched the folder of Codewarrior installation, and get MCU_S12Z_Assembler.pdf and MCU_S12Z_Compiler.pdf. In the MCU_S12Z_Assembler.pdf, there is "Chapter 12 Mixed C and Assembler Applications", and "12.1 Parameter Passing Scheme
Check the backend chapter in the compiler manual for the details of parameter passing."
But I did not find contents about parameter passing in MCU_S12Z_Compiler.pdf, do you know where can I find such contents? Thanks.
Hi, @ZhaiHui
What is McuInitModeType? Is it enum type? enum size is unspeciied, it may be 8bits, it may 16 bits. At least compiler may try to decide what is more optimal.
See chapter 18.4 calling convention.
Regards
Edward
Hello Edward,
Thank you very much for the answer. Yes, the McuInitModeType is enum, so I think it depends on compiler. We will try to modify it to primitive type. Thank you again.
Hello ZhaiHui,
The simplest way is to build the C-Function, then compile to assembler and copy the generated code into main assembler code. The advantage of this attempt is very simple procedure and you don’t need to save all possible affected registers used by compiled C-Function if it will be called from the asm code.
The next more complicated attempt is to define such exact position of the C-Function in *.prm file. Then if you want use this function you can use the “ld C_Addr” and “jmp ….” Command, but before you must save contents of all registers which could be used by compiled C-Function. In case you change this function you need to investigate which registers will be used by new C-Function and save possible other registers in asm code before use this function.
The other topic is the return from C-Function – you need to have saved the return address and use it when C-Function finishes.
So finally I suggest you to use the first option – write C-Function, compile it and copy the code into main asm code. It is more fluent asm code, more reliable and you don’t need pay attention to save the contents of many registers used by called C-Function.
I hope it can help you to solve your task.
Best Regards,
Stano.