C语言中嵌入汇编

2025-11-09 18:25:13

1、以下所说嵌入的汇编都是GUN 的C语言中嵌入ARM汇编。

1)2个参数的内嵌语句

这种形式的汇编用于简单的语句,参数限制输入和输出语法格式如下:

asm(code : output operand list : inputoperand list : clobber list);

汇编和C语句这间的联系是通过上面asm声明中可选的output operand list和input operand list。Clobber list后面再讲。

下面是将C语言的一个整型变量传递给汇编,逻辑左移一位后在传递给C语言的另外一个整型变量。

/* Rotating bits example */

asm("mov %[result], %[value], ror#1" : [result] "=r" (y) : [value] "r" (x));

每一个asm语句被冒号(:)分成了四个部分。

         汇编指令放在第一部分中的“”中间。

 "mov %[result], %[value], ror #1"

         接下来是冒号后的可选择的output operand list,每一个条目是由一对[](方括号)和被他包括的符号名组成,它后面跟着限制性字符串,再后面是圆括号和它括着的C变量。这个例子中只有一个条目。

 [result] "=r" (y)

         接着冒号后面是输入操作符列表,它的语法和输入操作列表一样

[value] "r" (x)

为了增加代码的可读性,你可以使用换行,空格,还有C风格的注释。

asm("mov %[result], %[value], ror#1"

          : [result]"=r" (y) /* Rotation result. */

          : [value]"r" (x) /* Rotated value. */

          : /* No clobbers */

);

在代码部分%后面跟着的是后面两个部分方括号中的符号,它指的是相同符号操作列表中的一个条目。

%[result]表示第二部分的C变量y,%[value]表示三部分的C变量x;

符号操作符的名字使用了独立的命名空间。这就意味着它使用的是其他的符号表。简单一点就是说你不必关心使用的符号名在C代码中已经使用了。在早期的C代码中,循环移位的例子必须要这么写:

asm("mov %0, %1, ror #1" :"=r" (result) : "r" (value))

在汇编代码中操作数的引用使用的是%后面跟一个数字,%1代表第一个操作数,%2代码第二个操作数,往后的类推。这个方法目前最新的编译器还是支持的。但是它不便于维护代码

实例代码:

C语言中嵌入汇编

2、2) 带.s文件的汇编

编译命令:

arm-linux-gcc  main.c Asmfile_gnu.s  -o mains

main.c

#include<stdio.h>

extern voidpcm8_2_pcm16(unsigned char* pIn, int nInlen, short* pOut);

extern voidpcm16_2_pcm8(short* pIn, int nInlen,unsigned char* pOut);

int main()

{     

       unsigned char* pIn="1234";

       short pInd[256];

       unsigned char pOutd[256];

       int nInlen=4;

       int i = 0;

       short pOut[256];

       for(i=0;i<4;i++)

               printf(" 0x%x  ",pIn[i]);

       printf("\n");

       memset((char *)pOut,0,256*2);

       memset((char *)pInd,0,256*2);  

       memset((char *)pOutd,0,256*2);

       pcm8_2_pcm16(pIn,nInlen,pOut);

       for(i=0;i<4;i++)

               printf(" 0x%x  ",pOut[i]);

       printf("\n");

       memcpy((char *)pInd,(char *)pOut,256*2);

       pcm16_2_pcm8(pInd,nInlen,pOutd);

       for(i=0;i<4;i++)

               printf(" 0x%x  ",pOutd[i]);

       printf("\n");

       return 0;

}

Asmfile_gnu.s

.text

.global pcm8_2_pcm16

.global pcm16_2_pcm8

#*******************************#

 #********* ENCODER 实现将第一个输入参数

 #左移8位然后异或0x8000 然后拷贝到第三个参数

 #DECODE 取第一个参数所指的数据先异或0x8000

 #然后右移8位将数据拷贝到第三个参数

 #*******************************

pcm8_2_pcm16:

       MOV R6,#0

       MOV R7,#0

ENCODER:

       LDRB R5,[R0,R6]

       MOV  R8,R5,LSL#8

       EOR  R9,R8,#0x8000

      STRH R9,[R2,R7]

       ADD  R7,R7,#2

       ADD  R6,R6,#1

      SUB  R1,R1,#1

      CMP  R1,#0

      BNE  ENCODER

      B    OVER

pcm16_2_pcm8:

       MOV  R6,#0

       MOV  R7,#0

DECODE:

       LDRH R5,[R0,R6]

       EOR  R8,R5,#0x8000

      MOV  R9,R8,LSR#8

      STRB R9,[R2,R7]

       ADD  R7,R7,#1

       ADD  R6,R6,#2

      SUB  R1,R1,#1

      CMP  R1,#0

      BNE  DECODE

OVER:

      .end

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢