我们使用m标记可以直接在内存中对数进行操作,前面的例子对变量进行操作时都需要将变量值存储在要修改的寄存器中,然后将它写回内存位置中.

#include <stdio.h>
int main(void){int xa=2;int xb=6;asm volatile("subl %1,%0\n\t" :"=r"(xb):"m"(xa),"0"(xb));    printf("%d\n",xb);return 0;
}

我们直接从xa的内存地址中将xa取出,而不需要再将xa先存储在一个寄存器。

首先,我们看一下AT&T汇编各段的意义

节 含义
.text 已编译程序的机器代码
.rodata 只读数据,如pintf和switch语句中的字符串和常量值
.data 已初始化的全局变量
.bss 未初始化的全局变量
.symtab 符号表,存放在程序中被定义和引用的函数和全局变量的信息
.rel.text 当链接器吧这个目标文件和其他文件结合时,.text节中的信息需修改
.rel.data 被模块定义和引用的任何全局变量的信息
.debug 一个调试符号表。
.line 原始C程序的行号和.text节中机器指令之间的映射
.strtab 一个字符串表,其内容包含.systab和.debug节中的符号表

上面列表也许比较抽象,我们从一个C程序生成的中间汇编代码分析:

#include <stdio.h>void main(){char *x="xxxx";char y[]="yy";//y的16进制ASCII码是97,9797的十进制为31097printf("%s-----%s",x,y);exit(0);}

我们使用gcc -S testcr.c,查看编译生成的汇编代码(为便于理解,将生成的汇编代码进行了注释)

.file   "testcr.c".section    .rodata.LC0:.string "xxxx"#使用char *分配.LC1:.string "%s-----%s".text.globl main.type   main, @functionmain:pushl   %ebpmovl    %esp, %ebpandl    $-16, %espsubl    $32, %esp#分配32字节栈空间,根据变量情况分配movl    $.LC0, 24(%esp)#x变量使用指针(4个字节大小),放入栈中,可以看到,变量分配靠近栈空间的尾部movw    $31097, 29(%esp)#字符'yy'移到main程序的栈中,直接将y变量的值放入栈中movb    $0, 31(%esp)#加上NULL标志,表示字符结束 movl    $.LC1, %eaxleal    29(%esp), %edxmovl    %edx, 8(%esp)movl    24(%esp), %edxmovl    %edx, 4(%esp)movl    %eax, (%esp)call    printfmovl    $0, (%esp)call    exit.size   main, .-main.ident  "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3".section    .note.GNU-stack,"",@progbits

在MAIN函数中char *分配在只读数据段中,实际使用时,只在程序栈中分配一个指针的空间。char[] 在程序栈中分配空间,然后直接使用movl、movw之类的汇编直接把值放入栈中空间。那么在其它函数中声明的呢,可以从以下程序中看出,仍然如此。

#include <stdio.h>void myprinf(){char *x="xxxx";char y[]="yy";//y的16进制ASCII码是97,9797的十进制为31097printf("%s-----%s",x,y);}void main(){int num=1;myprint();exit(0);}

生成的中间汇编代码为:

.file "testcr.c".section    .rodata.LC0:.string "xxxx".LC1:.string "%s-----%s".text.globl myprinf.type   myprinf, @functionmyprinf:pushl   %ebpmovl    %esp, %ebpsubl    $40, %espmovl    $.LC0, -16(%ebp)movw    $31097, -11(%ebp)movb    $0, -9(%ebp)movl    $.LC1, %eaxleal    -11(%ebp), %edxmovl    %edx, 8(%esp)movl    -16(%ebp), %edxmovl    %edx, 4(%esp)movl    %eax, (%esp)call    printfleaveret.size   myprinf, .-myprinf.globl main.type   main, @functionmain:pushl   %ebpmovl    %esp, %ebpandl    $-16, %espsubl    $32, %espmovl    $1, 28(%esp)call    myprintmovl    $0, (%esp)call    exit.size   main, .-main.ident  "GCC: (Ubuntu 4.4.3-4ubuntu5) 4.4.3".section    .note.GNU-stack,"",@progbits

内存的常用分配方式有:

第一,静态分配,所有名字在编译时绑定某个存储位置。不能在运行时改变
第二,栈分配,活动时压入系统栈。
第三,堆分配,以任意次序分配

C指针原理(9)-C内嵌汇编相关推荐

  1. C指针原理(6)-C内嵌汇编

    内联汇编的重要性体现在它能够灵活操作,而且可以使其输出通过 C 变量显示出来.因为它具有这种能力,所以 "asm" 可以用作汇编指令和包含它的 C 程序之间的接口.简单得说,内联汇 ...

  2. C指针原理(7)-C内嵌汇编

    如何在内联汇编中访问C程序的局部变量呢,请看下面这段代码. #include <stdio.h> int main(void){//不使用全局变量,必须使用扩展GNU的asm//格式为:a ...

  3. C指针原理(8)-C内嵌汇编

    #include <stdio.h> int main(void){int xa=6;int xb=2;int result;//使用占位符,由r表示,编译器自主选择使用哪些寄存器,%0, ...

  4. c语言汇编call的参数,内嵌汇编—第7节:参数、局部变量、CALL原理

    内嵌汇编-第7节:参数.局部变量.CALL原理 小风群:300275325 女神群:372452500(安卓,ISO,PC)全包揽,女神小敏期待你的加入哦. 这一节可能是大家最想明白的部分,想当初我为 ...

  5. ATT汇编语言与GCC内嵌汇编简介

    AT&T汇编语言与GCC内嵌汇编简介 1 AT&T 与INTEL的汇编语言语法的区别 1.1大小写 1.2操作数赋值方向 1.3前缀 1.4间接寻址语法 1.5后缀 1.6指令 2 G ...

  6. GCC如何编译内嵌汇编代码

    内核代码绝大部分使用C  语言编写,只有一小部分使用汇编语言编写,例如与特定体系结构相关的代码和对性能影响很大的代码.GCC提供了内嵌汇编的功能,可以在C代码中直接内嵌汇编语言语句,大大方便了程序设计 ...

  7. __asm__ __volatile__ GCC的内嵌汇编语法 ATT汇编语言语法(Z)

    此文在网上到处转载,已不知原出处,我也将之记录在此,并改正其中的一些小笔误. 开 发一个OS,尽管绝大部分代码只需要用C/C++等高级语言就可以了,但至少和硬件相关部分的代码需要使用汇编语言,另外,由 ...

  8. GCC的内嵌汇编语法 ATT汇编语言语法

    __asm__ __volatile__ GCC的内嵌汇编语法 AT&T汇编语言语法(一) 2007年05月09日 12:36 开 发一个OS,尽管绝大部分代码只需要用C/C++等高级语言就可 ...

  9. 转载:asm volatile GCC的内嵌汇编语法 ATT汇编语言语法

    asm volatile  GCC的内嵌汇编语法 AT&T汇编语言语法 目录 asm volatile  GCC的内嵌汇编语法 AT&T汇编语言语法 1 Overview 2.  GC ...

最新文章

  1. 各代程序设计语言拓扑
  2. seaborn系列 (4) | 分类图catplot()
  3. 交换两个数不引入第三个变量
  4. 用户登录,token验证开发(含过期时间)
  5. JavaOne 2016 Essentials:7个您不容错过的事件和会话
  6. 蓝牙驱动卸载后自动安装_最热建筑安装工程计算表格,输入后自动生成,省时方便易上手...
  7. leetcode513. 找树左下角的值(dfs)
  8. asio c++20 协程在windows下和linux下设定
  9. sql2018 ssas_如何使用SQL Server Analysis Services(SSAS)从头开始构建多维数据集
  10. 倍增LCA(bzoj 3732: Network)
  11. Azkaban时区问题导致调度差1天
  12. 菜鸟python爬虫scrapy_Python爬虫(Scrapy)爬取秀人网
  13. CAD文字快速添加框
  14. 巅峰之证!首位阿里云ACE认证专家产生
  15. D1: elevater design
  16. HR_NZ_ROUNDING_DECIMALS DUMP
  17. django读取mysql事实数据_Django读取Mysql数据并显示在前端的实例
  18. 基于TLC5615芯片的DDS信号发生器(FPGA)
  19. windows快速生成ssh key
  20. Typora的下载及MarkDown使用

热门文章

  1. 三角形问题——junit test 尝试
  2. [转]Linux环境下段错误的产生原因及调试方法小结
  3. Android 系统自带 Theme(主题)
  4. [C1W3] Neural Networks and Deep Learning - Shallow neural networks
  5. 素数 乘法表 闰年
  6. vue父子组件、兄弟组件之间的通信和访问
  7. Vuex-状态管理模式
  8. robotframework 配置过程中遇到的问题
  9. HTML5 Web SQL
  10. 【Android】Camera 使用浅析