lnlidawei

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

asm:  gcc - c语言的内联汇编学习(linux_gcc_c)

 

 

 

 

一、基本说明

 

    1、操作系统:rockylinux9

        [root@rocky c]# uname -a
        Linux rocky 5.14.0-162.6.1.el9_1.0.1.x86_64 #1 SMP PREEMPT_DYNAMIC Mon Nov 28 18:44:09 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

 

    2、内联汇编的语言环境:gcc  -  c语言

 

    3、gcc 版本信息:

        [root@rocky c]# gcc --version
        gcc (GCC) 11.3.1 20220421 (Red Hat 11.3.1-2)
        Copyright (C) 2021 Free Software Foundation, Inc.
        This is free software; see the source for copying conditions. There is NO
        warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

 

 

 

 

二、内联汇编说明

 

  1、asm的基本语法:

 1 __asm__    [__volatile__](
 2         
 3         "Instruction List"    // 汇编指令列表;
 4         
 5         : Output List        // 输出参数列表; “汇编语言”,将结果输出到“C语言的变量”; (C语言变量 = 汇编变量;)
 6         
 7         : input List        // 输入参数列表; “汇编语言”,从“C语言的变量”读取数据; (汇编变量 = C语言变量;)
 8         
 9         : Clobber/Modify    // 损坏部分; “汇编语言”会改变“寄存器”和“内存”的值;
10                             //    在汇编代码执行前,强迫gcc编译器备份此处声明的寄存器和内存的数值;
11                             //    在“汇编代码执行后”,恢复此处声明的寄存器和内存的值。
12                             // 概括:  汇编前,将重要数据备份; 汇编后,恢复现场。
13         );
14         

 

  2、示例代码及说明

 1       __asm__(
 2         " movl  %3,  %%ebx  \t\n"          // %3 = input2
 3         " movl  %2,  %%eax  \t\n"          // %2 = input1
 4         " movl  %%ebx,  %1  \t\n"        // %1 = output2
 5         " movl  %%eax,  %0     "        // %0 = output1
 6 
 7         : "=a"(output1), "=b"(output2)    // 为“汇编语言”提供输入和输出的“c语言变量”,“汇编语言”会分配一个别名给“C语言的这些变量”。
 8         : "r"(input1), "r"(input2)        // 汇编语言别名分配规则:
 9                                         //        开始于“Output List”的左端,第一个C语言变量的别名为0;右端结束;
10                                         //         结束于“Input List”的右端,最后一个C语言变量的别名小于等于9.
11                                         //    别名:        output1=0,  output2=1,  input1=2,  input2=3.
12       );

 

 

 

 

三、源码及运行结果

 

 1 [root@rocky c]# uname  -a
 2 Linux rocky 5.14.0-162.6.1.el9_1.0.1.x86_64 #1 SMP PREEMPT_DYNAMIC Mon Nov 28 18:44:09 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
 3 [root@rocky c]# 
 4 [root@rocky c]# 
 5 [root@rocky c]# gcc  --version
 6 gcc (GCC) 11.3.1 20220421 (Red Hat 11.3.1-2)
 7 Copyright (C) 2021 Free Software Foundation, Inc.
 8 This is free software; see the source for copying conditions.  There is NO
 9 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10 
11 [root@rocky c]# 
12 [root@rocky c]# 
13 [root@rocky c]# gcc -Wall -g -o asm_test asm_test.c && cat asm_test.c && ./asm_test 
14 #include<stdio.h>
15 #include<stdlib.h>
16 
17 
18 
19 
20 void
21 msg()
22 {
23   int input1 = 91;
24   int input2 = 92;
25   int output1 = 11;
26   int output2 = 12;
27   printf("\n\nbefore-asm:\toutput1=%d,\toutpu2=%d\n", output1, output2);
28 
29 
30   // function: output1 = input1;  output2 = input2;
31   // result:  output1 = 91;  output2 = 92;
32   __asm__(
33     " movl  %3,  %%ebx  \t\n"   // %3 = input2 
34     " movl  %2,  %%eax  \t\n"   // %2 = input1
35     " movl  %%ebx,  %1  \t\n"   // %1 = output1
36     " movl  %%eax,  %0     "    // %0 = output1
37 
38     : "=a"(output1), "=b"(output2)      // nickname: output1 = %0, output2 = %1; 
39     : "r"(input1), "r"(input2)          // nickname: input1 = %2, input2= %3
40   );                                    //    nickname N: 0 <= N  <=9; 
41                                         //    from OUTPUT(left-to-right) to end INPUT(left-to-right)
42 
43 
44   printf("after-asm:\toutput1=%d,\toutpu2=%d\n\n", output1, output2);
45 }
46 
47 
48 
49 
50 int main(int argc, char *argv[], char *envp[])
51 {
52   msg();
53 
54   return 0;
55 }
56 
57 
58 before-asm:     output1=11,     outpu2=12
59 after-asm:      output1=91,     outpu2=92
60 
61 [root@rocky c]# 
62 [root@rocky c]# 

 

 

 

 

 

 

四、参考文献

 

  1、AT&T汇编语言(中文版):   https://max.book118.com/html/2015/1010/27027193.shtm

 

  2、GCC内联汇编:   https://www.cnblogs.com/hellokitty2/p/16344565.html

 

  3、GCC 内联汇编语法:   https://blog.csdn.net/zxjcarrot/article/details/12886085

 

  4、GCC内联汇编: http://www.360doc.com/content/15/0604/12/496343_475591449.shtml

 

posted on 2022-12-31 00:54  lnlidawei  阅读(309)  评论(0编辑  收藏  举报