GCC内联汇编(2)GCC生成汇编代码简单实例
来源:互联网 发布:java在线考试系统代码 编辑:程序博客网 时间:2024/05/29 03:14
GCC内联汇编(2)GCC生成汇编代码简单实例
- 作者:柳大·Poechant(钟超)
- 邮箱:zhongchao.ustc#gmail.com(# -> @)
- 博客:Blog.CSDN.net/Poechant
- 日期:July 8th, 2012
1 准备示例
先看一个空的 main 函数会生成怎样的汇编代码。要注意的是我这里是在 Mac OS X 上进行的测试,编译器是 Apple’s version of GCC,实际上用的是 llvm-gcc。
[代码段-1]
int main() { return 0;}
[命令行-1]
gcc -S main.c
生成的汇编如下(这里只截取主要部分,下同):
[代码段-2]
Leh_func_begin1: pushq %rbpLtmp0: movq %rsp, %rbpLtmp1: movl $0, -8(%rbp) movl -8(%rbp), %eax movl %eax, -4(%rbp) movl -4(%rbp), %eax pop %rbp retLeh_func_end1:
如果开启优化编译选项呢?一定会有一些变化吧。
[命令行-2]
gcc -S main.c -O3
[代码段-3]
Leh_func_begin1: pushq %rbpLtmp0: movq %rsp, %rbpLtmp1: xorl %eax, %eax popq %rbp pop %rbp retLeh_func_end1:
是的,一些“废话”被优化掉了。
[代码段-4]
int main() { int a = 19, b = 100; return 0;}
看下面的简单实例,声明两个整形变量,并赋以初值。
[命令行-3]
gcc -S main.c
生成的汇编代码如下。可以看到 a 代表的局部变量值 19 被压入栈中,位置是栈基址减去 12,b 代表的局部变量压入栈中,位置是栈基址减去 16,而返回值所使用的立即数 0 被放入栈基址减去 8。
[代码段-5]
Leh_func_begin1: pushq %rbpLtmp0: movq %rsp, %rbpLtmp1: movl $19, -12(%rbp) movl $100, -16(%rbp) movl $0, -8(%rbp) movl -8(%rbp), %eax movl %eax, -4(%rbp) movl -4(%rbp), %eax pop %rbp retLeh_func_end1:
如果打开优化编译选项编译,则会把int a = 19, b = 100
这句优化掉,从而与[代码段-3]一样。
2 内联汇编实例
int main(){ int a = 19, b = 100; __asm__ ( "addl %2, %1"; : "=a"(a) : "a"(a), "b"(b) : "%eax", "%ebx" ) return 0;}
生成的汇编如下:
_main:Leh_func_begin1: pushq %rbpLtmp0: movq %rsp, %rbpLtmp1: pushq %rbx subq $24, %rspLtmp2: movl $19, -20(%rbp) # 局部变量 a 的位置是栈基址减去 20 movl $100, -24(%rbp) # 局部变量 b 的位置是栈基址减去 24 # 处理内敛汇编的入口 movl -20(%rbp), %eax movl -24(%rbp), %ecx movl %ecx, %ebx ## InlineAsm Start addl %ebx, %eax; ## InlineAsm End movl %eax, -20(%rbp) # 返回值放在指定的局部变量 a 中 # 剩下的部分与前面的简单实例一样,就是处理返回值 movl $0, -16(%rbp) movl -16(%rbp), %eax movl %eax, -12(%rbp) movl -12(%rbp), %eax popq %rbx popq %rbp ret Leh_func_end1:
#include int main() { int a = 19, b = 100; __asm__ ( "addl %1, %0;" : //no output : "a"(a), "b"(b) : "%eax", "%ebx" ); return 0;}
_main:Leh_func_begin1: pushq %rbpLtmp0: movq %rsp, %rbpLtmp1: pushq %rbxLtmp2: # Immediate numbers movl $19, -20(%rbp) movl $100, -24(%rbp) # Input movl -20(%rbp), %eax movl -24(%rbp), %ecx movl %ecx, %ebx ## InlineAsm Start addl %ebx, %eax; ## InlineAsm End # Note: no output # Similar to above examples movl $0, -16(%rbp) movl -16(%rbp), %eax movl %eax, -12(%rbp) movl -12(%rbp), %eax popq %rbx popq %rbp ret Leh_func_end1:
也间接证实了%0
, %1
, %2
⋯⋯ 是从输出开始排序的,如果没有输出,就从输入开始排序。
另外使用m
则可以表示memory
,即变量是在内存中,而非寄存器中。如下示例:
#include int main() { int a = 17, b = 100; __asm__ ( "addl %2, %1;" : "=m"(a) : "m"(a), "b"(b) : "memory", "%ebx" ); printf("%d\n", a); return 0;}
生成的汇编代码的主要部分如下:
movl $17, -20(%rbp)movl $100, -24(%rbp)movl -24(%rbp), %eaxmovl %eax, %ebx## InlineAsm Startaddl %ebx, -20(%rbp)## InlineAsm End## 下面的部分同此前的所有代码段,略去
可以看到是直接加到操作上的,而非寄存器。
-
转载请注明来自柳大的CSDN博客:Blog.CSDN.net/Poechant
-
- GCC内联汇编(2)GCC生成汇编代码简单实例
- Gcc内联汇编2
- gcc 生成汇编代码
- gcc内联汇编
- GCC内联汇编基础
- GCC内联汇编
- GCC内联汇编入门
- GCC内联汇编基础
- GCC内联汇编
- Gcc内联汇编1
- GCC内联汇编基础
- gcc内联汇编入门
- GCC 内联汇编
- GCC内联汇编基础
- gcc内联汇编
- GCC 内联汇编测试
- GCC内联汇编
- GCC 内联汇编
- 再谈以客户为中心——见识大神了
- vim编辑二进制文件
- Windows8 RP版亲手体验全过程
- centos 邮件服务器postfix,saslauthd,dovecot安装配置.
- GCC内联汇编(1)Get started
- GCC内联汇编(2)GCC生成汇编代码简单实例
- 【Visual C++】游戏开发笔记二十八 最精简的Direct3D11 Demo筋骨脉络全攻略
- 写给要结束大一的孩子——飞出个样子来
- 福特蒙迪欧致胜窗户不能一键升降的解决方法
- 怎么超越大卡车或其它大型车辆
- 关于电子商务网站的聊天
- 车辆出险保险索赔技巧- 如果您的车有幸在地震中被建筑物砸到的话
- 车辆出险保险索赔技巧- 如果您的爱车在一次急刹车中,车里的东东飞到了风挡上造成玻璃破裂。您该怎么说呢?
- 车辆出险保险索赔技巧- 您如果在拖车时与别的车发生了碰撞时