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