x86汇编语言(五)
来源:互联网 发布:天刀红唇萌妹捏脸数据 编辑:程序博客网 时间:2024/05/18 06:28
GCC中启用intel风格的内联汇编
gcc中默认的内联汇编格式默认为AT&T格式,我们可以主动声明intel风格的内联汇编——asm(".intel_syntax noprefix\n"),编译时使用-masm=intel选项,此时源文件中的汇编代码就可以得到正确处理。以下为示例程序:
#include<stdio.h>int main(){ int a = 1,b = 2; asm(".intel_syntax noprefix\n"); asm("mov dword ptr a,3\n"); a = a + b; printf("%d\n",a); return 0;}
使用gcc进行编译:gcc -masm=intel asm_test.c -o asm_test
然而编译失败,输出错误提示:/usr/bin/ld: /tmp/ccmEXVmu.o: relocation R_X86_64_32S against undefined symbol `a' can not be used when making a shared
a是一个未定义的符号所以出错。分析原因,a是一个局部变量,存储位置在栈空间,编译器对变量a的引用是通过 rbp+偏移量 的方式进行的,所以我们对a的引用也要使用 rbp+偏移量的方式,关键问题是确定a在堆栈中的偏移量。
对于如下代码,
#include<stdio.h>int main(){ int a; int b; int c; int d; int f; a = 10; b = 10; c = 10; d = 10; f = 10; printf("%d\n",a); return 0;}我们对其进行编译得到汇编代码:
.file"intel_asm.c".intel_syntax noprefix.section.rodata.LC0:.string"%d\n".text.globlmain.typemain, @functionmain:.LFB0:.cfi_startprocpushrbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movrbp, rsp.cfi_def_cfa_register 6subrsp, 32movDWORD PTR -20[rbp], 10movDWORD PTR -16[rbp], 10movDWORD PTR -12[rbp], 10movDWORD PTR -8[rbp], 10movDWORD PTR -4[rbp], 10moveax, DWORD PTR -20[rbp]movesi, eaxleardi, .LC0[rip]moveax, 0callprintf@PLTmoveax, 0leave.cfi_def_cfa 7, 8ret.cfi_endproc.LFE0:.sizemain, .-main.ident"GCC: (Ubuntu 6.2.0-5ubuntu12) 6.2.0 20161005".section.note.GNU-stack,"",@progbits
我们可以看到,对于局部变量a的是通过 -20[rbp] 来进行引用的,对于局部变量f是通过 -4[rbp] 进行引用的,而堆栈又是从高地址向低地址生长,这说明gcc对于局部变量的处理是先声明后如栈,这与vc的处理方式不同,通过查阅资料可知,这是由于gcc采用了一种名为SSP的堆栈保护技术导致的,我们使用-fno-stack-protector选项不使用该技术再次编译该文件:
.file"intel_asm.c".intel_syntax noprefix.section.rodata.LC0:.string"%d\n".text.globlmain.typemain, @functionmain:.LFB0:.cfi_startprocpushrbp.cfi_def_cfa_offset 16.cfi_offset 6, -16movrbp, rsp.cfi_def_cfa_register 6subrsp, 32movDWORD PTR -4[rbp], 10movDWORD PTR -8[rbp], 10movDWORD PTR -12[rbp], 10movDWORD PTR -16[rbp], 10movDWORD PTR -20[rbp], 10moveax, DWORD PTR -4[rbp]movesi, eaxleardi, .LC0[rip]moveax, 0callprintf@PLTmoveax, 0leave.cfi_def_cfa 7, 8ret.cfi_endproc.LFE0:.sizemain, .-main.ident"GCC: (Ubuntu 6.2.0-5ubuntu12) 6.2.0 20161005".section.note.GNU-stack,"",@progbits
此时可以看到,对于变量a的引用已经是 -4[rbp] 了,这说明变量a先入栈。
现在修改我们的示例文件,由以上可知,对于变量a的引用应该是 -8[rbp]
#include<stdio.h>int main(){ int a = 1,b = 2; asm(".intel_syntax noprefix\n"); asm("mov dword ptr [rbp -8],3\n"); a = a + b; printf("%d\n",a); return 0;}jyj6536@jyj6536-VirtualBox:~/文档/C语言2/2$ gcc -masm=intel asm_test.c -o asm_test
jyj6536@jyj6536-VirtualBox:~/文档/C语言2/2$ ./asm_test
5
结果正确
阅读全文
0 0
- x86汇编语言(五)
- X86汇编语言(前言)
- x86汇编语言(一)
- x86汇编语言(二)
- x86汇编语言(三)
- X86汇编语言(四)
- 杨季文 80x86汇编语言程序设计 实例五
- X86 汇编语言
- 汇编语言程序设计(五)
- 80x86汇编语言学习笔记(一)
- 80x86汇编语言学习笔记(三)
- 80x86汇编语言学习笔记(四)
- 程序的加载和执行(五)——《x86汇编语言:从实模式到保护模式》读书笔记25
- 任务和特权级保护(五)——《x86汇编语言:从实模式到保护模式》读书笔记36
- 《汇编语言》学习(五)循环
- 简明x86汇编语言教程
- X86汇编语言学习手记
- 简明x86汇编语言教程
- Python+selenium
- 对象、对象引用、实例
- 【理论实践】用alignas代替#pragma pack
- PHP根据经纬度获取地址信息
- 实用插件(五)弹出操作提示框artdialog
- x86汇编语言(五)
- Celery任务队列
- android——Glide框架总结笔记
- 【DL--18】Windows下基于Anaconda的Tensorflow环境配置
- mysql引擎Innodb和Myisam对比介绍和优缺点
- mysql通过mysqldump和mysqlbinlog恢复数据,binlog恢复数据失败解决方案
- Adapter的代码片段
- BlockScanary --监视主线程上卡顿工具
- Spark运行模式