转载自http://blog.csdn.net/qqliyunpeng/article/details/48791647
一、GNU汇编书写格式:
- 代码行中的注释符号: ‘@’ 整行注释符号: ‘#’ 语句分离符号: ‘;’ 直接操作数前缀: ‘#’ 或 ‘$’
- 全局标号:标号只能由a~z,A~Z,0~9,“.”,_等(由点、字母、数字、下划线等组成,除局部标号外,不能以数字开头)字符组成,标号的后面加“:”。
段外标号的地址值在连接时确定。
- 局部标号:局部标号 主要在局部范围内使用而且局部标号可以重复出现。它由两部组成开头是一个0-99直接的数字局部标号 后面加“:”???
F:指示编译器只向前搜索,代码行数增加的方向
/ 代码的下一句
B:指示编译器只向后搜索,代码行数减小的方向
注意局部标号的跳转,就近原则
例子:
1:a
2:b
1:c
b 1b 跳转到 c 所处的位置
==================================================================
gcc -c 1.c -o 1.o
gcc -c 2.c -o 2.o
ld -Ttext 40008000 1.o 2.o -o a.elf
gcc -c 1.s -o 1.o
gcc -c 2.c -o 2.o
ld -Ttext 40008000 1.o 2.o -o a.elf
在汇编中.global/.globl (在定义的文件中)
在 c 中extern (在调用的文件中)
================
内联汇编 ============
(1)Gcc 通过关键字“asm”来声明内联汇编
(2)格式: asm或__asm__开头,小括号+分号,括号内容写汇编指令。
指令+
\n\t 用双引号引上
asm(code : output operand list : input operand list : clobber list);
(3)例一:无参数,无返回值
asm
(
//汇编指令
"mrs r0,cpsr \n\t"
"bic r0,r0,#0x80 \n\t"
"msr cpsr,r0 \n\t"
);
(4)
例二:有参数 1,有返回值
让内联汇编做加法运算,求a+b,结果存在c中
int a =100;
int b =200;
int c =0;
asm
(
"add
%0,%1,%2\n\t"
: "=r"(c) //
输出列表 %0 --c
: "r"(a),"r"(b) //
输入列表 %1 --a %2--b
: "memory" //
通知列表
);
例三:有参数 2 ,有返回值
让内联汇编做加法运算,求a+b,结果存在c中,把a-b的存在d中
int a=100;
int b=200;
int c=0;
int d=0;
asm volatile
(
"add
%[op1],%[op2],%[op3]\n\t"
:[op1]"=r”(sum)
:[op2]"r"(a),
[op3]”r”(b)
:"memory"
" sub
%[op4],%[op2],%[op3]\n\t "
:[%op4]"=r"(d)
:
:"memory"
);
4级 O0 -- O3 数字越大,优化程度越高。
O3最大优化
volatile修饰的变量,编译器
不再进行
优化,每次都真正访问内存地址空间。