如何在CodeWarrior中的C文件中调用汇编代码?

时间:2022-03-23 03:15:47

The professor would like us to program a part of the program using assembly code, and then he would like us to call this code from within a C program, and then jump back to the C program when it is completed. I can't seem to find any documentation on this. I am using the Dragon12 board that uses an 68HC12, if it matters. It doesn't sound like he wants us to use the in-line asm() function.

教授希望我们使用汇编代码编写程序的一部分,然后他希望我们从C程序中调用此代码,然后在完成后跳回C程序。我似乎无法找到任何关于此的文档。我正在使用使用68HC12的Dragon12板,如果重要的话。这听起来并不像他希望我们使用内联asm()函数。

4 个解决方案

#1


1  

You can call a function defined in assembly just as any normal function in C (provided you use the proper calling convention), just make sure the return type and arguments match. For example, if the assembly looks like:

您可以像在C中的任何普通函数一样调用程序集中定义的函数(假设您使用正确的调用约定),只需确保返回类型和参数匹配即可。例如,如果程序集如下所示:

my_func:
    ; assembly code here
    ; some more assembly code
    ; etc.
    xor ax, ax
    ret

Then you can call it from C as follows:

然后你可以从C调用它,如下所示:

extern int my_func();

// ...
int zero = my_func();

#2


0  

The help menu documentation for CodeWarrior Development Studio 10.5 describes how to call pure assembly language functions from within C/C++ code as follows:

CodeWarrior Development Studio 10.5的帮助菜单文档描述了如何从C / C ++代码中调用纯汇编语言函数,如下所示:

The labels defined in an assembly file have local scope. To access them from the other file (the .c file) they should be marked as global. For example, .global _my_asm_func.

程序集文件中定义的标签具有本地范围。要从其他文件(.c文件)访问它们,应将它们标记为全局。例如,。global _my_asm_func。

To illustrate, here is an example code snippet:

为了说明,这是一个示例代码片段:

.global _my_asm_func
.text

_my_asm_func:
    subq.l   #4,a7
    move.l   d1,(a7)
    add.l    (a7),d0
    addq.l   #4,a7
    rts

In your C/C++ code, first declare a prototype for the function. For example, int my_asm_func(int a, int b);. Then call that function like any other C/C++ function. For example, my_asm_func(5, 2);.

在C / C ++代码中,首先声明函数的原型。例如,int my_asm_func(int a,int b);.然后像任何其他C / C ++函数一样调用该函数。例如,my_asm_func(5,2);.

Notice that in the assembly code, the function is prefixed with an underscore, but in the C/C++ it is not. I am not sure if this is required, or just convention.

请注意,在汇编代码中,函数以下划线为前缀,但在C / C ++中则不是。我不确定这是否是必需的,或者只是惯例。

Parameters are passed into sequential data registers. In this case, you would expect to find 5 in D0 and 2 in D1.

参数传递到顺序数据寄存器。在这种情况下,您可能会在D0中找到5,在D1中找到2。

#3


0  

question long ago but answer might still help.

问题很久以前但回答可能仍然有帮助。

For Kinetis MCU and gcc, maybe the following snippet might illustrate a possibility. (It was part of my fault handler) Below, the "PE_ISR" interrupt uses inline assembler to call the FaultHandlerAsm function, which in turn is also inline-assembler. At the end, it branches to a c-function "faultHandlerC", which is not included here.

对于Kinetis MCU和gcc,可能以下代码段可能会说明这种可能性。 (它是我的错误处理程序的一部分)下面,“PE_ISR”中断使用内联汇编程序来调用FaultHandlerAsm函数,而函数又是内联汇编程序。最后,它分支到一个c函数“faultHandlerC”,这里不包括它。

void FaultHandlerAsm(void)
{
  __asm volatile (
    " movs r0,#4       \n"
    " movs r1, lr      \n"
    " tst r0, r1       \n"
    " beq _MSP         \n"
    " mrs r0, psp      \n"
    " b _HALT          \n"
  "_MSP:               \n"
    " mrs r0, msp      \n"
  "_HALT:              \n"
    " ldr r1,[r0,#20]  \n"
    " b FaultHandlerC  \n"
    //" bkpt #0          \n"
  );
}

PE_ISR(Cpu_INT_Hard_FaultInterrupt)
{
   __asm(    " b FaultHandlerAsm \n");
}  

#4


-1  

The easiest way to find out the proper way of calling your function is just to write a function in C with the same arguments and return, doing some minimal work inside (access each argument, fill in result value), and compile to assembler. Identify how each of the operations that interest you are done, and you are set.

找出调用函数的正确方法的最简单方法就是在C中用相同的参数编写一个函数并返回,在内部做一些最小的工作(访问每个参数,填入结果值),然后编译成汇编程序。确定您感兴趣的每项操作是如何完成的,并确定您的设置。

#1


1  

You can call a function defined in assembly just as any normal function in C (provided you use the proper calling convention), just make sure the return type and arguments match. For example, if the assembly looks like:

您可以像在C中的任何普通函数一样调用程序集中定义的函数(假设您使用正确的调用约定),只需确保返回类型和参数匹配即可。例如,如果程序集如下所示:

my_func:
    ; assembly code here
    ; some more assembly code
    ; etc.
    xor ax, ax
    ret

Then you can call it from C as follows:

然后你可以从C调用它,如下所示:

extern int my_func();

// ...
int zero = my_func();

#2


0  

The help menu documentation for CodeWarrior Development Studio 10.5 describes how to call pure assembly language functions from within C/C++ code as follows:

CodeWarrior Development Studio 10.5的帮助菜单文档描述了如何从C / C ++代码中调用纯汇编语言函数,如下所示:

The labels defined in an assembly file have local scope. To access them from the other file (the .c file) they should be marked as global. For example, .global _my_asm_func.

程序集文件中定义的标签具有本地范围。要从其他文件(.c文件)访问它们,应将它们标记为全局。例如,。global _my_asm_func。

To illustrate, here is an example code snippet:

为了说明,这是一个示例代码片段:

.global _my_asm_func
.text

_my_asm_func:
    subq.l   #4,a7
    move.l   d1,(a7)
    add.l    (a7),d0
    addq.l   #4,a7
    rts

In your C/C++ code, first declare a prototype for the function. For example, int my_asm_func(int a, int b);. Then call that function like any other C/C++ function. For example, my_asm_func(5, 2);.

在C / C ++代码中,首先声明函数的原型。例如,int my_asm_func(int a,int b);.然后像任何其他C / C ++函数一样调用该函数。例如,my_asm_func(5,2);.

Notice that in the assembly code, the function is prefixed with an underscore, but in the C/C++ it is not. I am not sure if this is required, or just convention.

请注意,在汇编代码中,函数以下划线为前缀,但在C / C ++中则不是。我不确定这是否是必需的,或者只是惯例。

Parameters are passed into sequential data registers. In this case, you would expect to find 5 in D0 and 2 in D1.

参数传递到顺序数据寄存器。在这种情况下,您可能会在D0中找到5,在D1中找到2。

#3


0  

question long ago but answer might still help.

问题很久以前但回答可能仍然有帮助。

For Kinetis MCU and gcc, maybe the following snippet might illustrate a possibility. (It was part of my fault handler) Below, the "PE_ISR" interrupt uses inline assembler to call the FaultHandlerAsm function, which in turn is also inline-assembler. At the end, it branches to a c-function "faultHandlerC", which is not included here.

对于Kinetis MCU和gcc,可能以下代码段可能会说明这种可能性。 (它是我的错误处理程序的一部分)下面,“PE_ISR”中断使用内联汇编程序来调用FaultHandlerAsm函数,而函数又是内联汇编程序。最后,它分支到一个c函数“faultHandlerC”,这里不包括它。

void FaultHandlerAsm(void)
{
  __asm volatile (
    " movs r0,#4       \n"
    " movs r1, lr      \n"
    " tst r0, r1       \n"
    " beq _MSP         \n"
    " mrs r0, psp      \n"
    " b _HALT          \n"
  "_MSP:               \n"
    " mrs r0, msp      \n"
  "_HALT:              \n"
    " ldr r1,[r0,#20]  \n"
    " b FaultHandlerC  \n"
    //" bkpt #0          \n"
  );
}

PE_ISR(Cpu_INT_Hard_FaultInterrupt)
{
   __asm(    " b FaultHandlerAsm \n");
}  

#4


-1  

The easiest way to find out the proper way of calling your function is just to write a function in C with the same arguments and return, doing some minimal work inside (access each argument, fill in result value), and compile to assembler. Identify how each of the operations that interest you are done, and you are set.

找出调用函数的正确方法的最简单方法就是在C中用相同的参数编写一个函数并返回,在内部做一些最小的工作(访问每个参数,填入结果值),然后编译成汇编程序。确定您感兴趣的每项操作是如何完成的,并确定您的设置。